链表基础
定义链表节点
//定义链表节点
struct ListNode {
int val;// 节点上存储的元素
ListNode *next;// 指向下一个节点的指针
ListNode() : val(0), next(nullptr) {} // 节点的构造函数
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
//初始化一个空链表,定义一个指针并将其初始化为 nullptr,作链表头
ListNode *head = nullptr;
head = new ListNode; //分配新结点
head->value = 12.5; //存储值
head->next = nullptr; //表示链表的结尾
//增加一个新链表节点
ListNode *secondPtr = new ListNode(13.5);
ListNode *head = new ListNode(12.5, secondPtr);
//插入一个节点-尾插法
ListNode* insertNode(ListNode* head, int data){
ListNode* newNode = new ListNode(data);
ListNode* p = head;
if (p == nullptr){
head = newNode;
}
else{
while (p->next != nullptr){
p = p->next;
}
p->next = newNode;
}
return head;
}
数组与链表比较
203-移除链表元素
思路
-
建一个虚拟节点dummyHead,dummyHead指向head节点,cur节点=dummyHead节点
-
接下来对cur->next节点进行操作,符号删除条件,就新建一个deleteNode节点,代表cur->next节点将要被删除
cur->next = cur->next->next;//把节点cur的指针域换成节点cur->next的指针域 -
不符合删除条件就cur = cur->next,看下一个节点
code
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
ListNode* cur = dummyHead;
while (cur->next != nullptr)
{
if(cur->next->val == val) {
ListNode* deleteNode = cur->next;
cur->next = cur->next->next;//把节点cur的指针域换成节点cur->next的指针域
delete deleteNode;
} else {
cur = cur->next;//节点之间的替换
}
}
head=dummyHead->next;//防止head节点被删除了的情况
delete dummyHead;
return head;
}
};
707-设计链表
思路
debug中
code
注意点
206-反转链表
双指针法
code
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==nullptr||head->next==nullptr){
return head;
}
ListNode* cur=head->next;
ListNode* pre=head;
pre->next=nullptr;//刚开始因为少了这一句,导致反转到head节点之后还有不断的链表,指针越界
ListNode* temp=new ListNode;
while(cur->next!=nullptr){
temp=cur->next;
cur->next=pre;
pre=cur;
cur=temp;
}
cur->next=pre;
return cur;
}
};
最开始将pre=head之后,没有令pre->next==nullptr,就导致如下图。
然后cur->next=pre之后,为什么会改变pre->next->next的值啊???