前言
本系列本意是基于面试而记录的一些有复习意义的题目,算是个人向的一个错题集。
问题
上周面试遇到链表类的题目,出了两个函数题,分别是链表节点删除和链表倒序。
我链表倒序死活没想出来,因为确实有点绕,故这篇文章重点记录一下链表倒序。
一、链表倒序算法
先定义链表节点结构体:
cpp
// 链表节点
struct ListNode{
int data;
ListNode * next;
ListNode(int val) : data(val), next(nullptr) {}
};
链表倒序算法:
cpp
// 链表倒转
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr != nullptr) {
ListNode* nextTemp = curr->next; // 1. 暂存下一个节点,防止断链
curr->next = prev; // 2. 反转当前节点的指针方向
prev = curr; // 3. 整体向前推进指针
curr = nextTemp;
}
return prev; // 循环结束后,prev 就是新的头节点
}
二、链表常见操作的完整测试代码
以下测试代码中,包含了链表遍历、插入、删除、倒序等常见的操作。
cpp
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
// 链表节点
struct ListNode{
int data;
ListNode * next;
ListNode(int val) : data(val), next(nullptr) {}
};
// 遍历
void fun_1(ListNode * head)
{
ListNode * cur = head;
while(cur){
qDebug()<< "cur" << cur->data;
cur = cur->next;
}
qDebug()<<"fun_1 finish ... ";
}
// 插入(在某个特定数据节点后插入)
ListNode * insertNode(ListNode * head, int data_after, int data_new){
ListNode * newNode = new ListNode(data_new);
ListNode * cur = head;
if(!cur){
head = newNode;
return head;
}
if(cur->data == data_after){
newNode->next = cur->next;
cur->next = newNode;
return head;
}
while(cur->next){
if(cur->next->data == data_after){
newNode->next = cur->next->next;
cur->next->next = newNode;
return head;
break;
}
cur= cur->next;
}
// not found
// cur->next = newNode;
delete newNode;
return head;
}
// 删除节点
ListNode * deleteNode(ListNode * head, int key){
if(!head) {
return nullptr;
}
if(head->data == key){
ListNode * tempNode = head;
head = head->next;
delete tempNode;
return head;
}
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr != nullptr && curr->data != key) {
prev = curr;
curr = curr->next;
}
if(!curr){
//not found
return head;
}
prev->next = curr->next;
delete curr;
return head;
}
// 链表倒转
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr != nullptr) {
ListNode* nextTemp = curr->next; // 1. 暂存下一个节点,防止断链
curr->next = prev; // 2. 反转当前节点的指针方向
prev = curr; // 3. 整体向前推进指针
curr = nextTemp;
}
return prev; // 循环结束后,prev 就是新的头节点
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
ListNode* head = new ListNode(1);
head->next = new ListNode(2);
head->next->next = new ListNode(3);
head->next->next->next = new ListNode(4);
head->next->next->next->next = new ListNode(5);
fun_1(head);
head = insertNode(head, 2, 8);
fun_1(head);
head = deleteNode(head, 4);
fun_1(head);
head = reverseList(head);
fun_1(head);
return a.exec();
}
运行结果:
