203.移除链表元素
文章链接:代码随想录 (programmercarl.com)
视频链接:手把手带你学会操作链表 | LeetCode:203.移除链表元素_哔哩哔哩_bilibili
这道题目还挺简单的 Carl哥讲的特别清晰 !!!!
考察单链表的删除元素的操作 分为两种解法:
1.不使用虚拟头节点
2.使用虚拟头节点
移除头节点和非头节点的操作是不一样的,若加一个虚拟头节点,代码可以实现统一,能方便许多!
1、不使用虚拟头节点
a.删除头节点
注意:头节点不可以为空;C++语言写的代码,删除结点之后,记得释放内存哦!
//不使用虚拟头节点
//a.删除头节点
while(head!=NULL&&head->val==val)
{
ListNode* temp=head;
head=head->next;
delete temp;
}
在这个代码中,为什么head不等于空,因为要操纵头结点的值,如果为空就是操纵头指针了
head->val等于要删除的值
这两个都是删除头结点时要满足的条件
b.删非头节点
创建一个指针 指向头节点,因为删除的是非头节点,指针需要指向头节点,如果指向其他节点,删除非头节点后,又因为是单链表,头节点没做记录,没办法将链表连接起来了!
//b.删非头节点
ListNode* cur=head;
while(cur!=NULL&&cur->next!=NULL)
{
if(cur->next->val==val)
{
ListNode* temp=cur->next;
cur->next=cur->next->next;
delete temp;
}
else{
cur=cur->next;
}
}
2、使用虚拟头节点
在头节点之前创建一个虚拟头节点,不管是删除头节点还是非头节点,都可以用统一的一段代码,只需要释放掉删除节点的内存空间和创建的虚拟头节点的内存空间!
这里的cur仍然指向链表的第一个节点,即为创建的虚拟头节点
//使用虚拟头节点
ListNode* dummyhead=new ListNode(0);
dummyhead->next=head;
ListNode* cur=dummyhead;
while(cur->next!=NULL)
{
if(cur->next->val==val)
{
ListNode* temp=cur->next;
cur->next=cur->next->next;
delete temp;
}
else{
cur=cur->next;
}
}
return dummyhead->next;
delete dummyhead;
707.设计链表
文章链接:代码随想录 (programmercarl.com)
视频链接:帮你拿下反转链表 | LeetCode:206.反转链表 | 双指针法 | 递归法_哔哩哔哩_bilibili
虚拟头节点是一个局部节点变量,程序结束后自动释放内存,并没有造成内存泄漏。//这句话参考链表第二天:虚拟头节点_为什么定义了虚拟头节点之后,释放时要用虚拟-CSDN博客
以下代码参考代码随想录 代码随想录 (programmercarl.com)
1、获取第N个节点的值
首先对N做一个合法判断,如果n小于0或者n大于链表节点数量,则是不合法的,创造cur指针指向头节点,然后while循环获取节点值即可
//1.获取第n节点的值
int get(int index)
{
if(index<0||index>(size-1))
{
return -1;
}
//创造cur指针, 将该指针指向头节点 利用while循环遍历 找到第n个节点的值
LinkedNode * cur=_dummyHead->next;
while(index)
{
cur=cur->next;
index--;
}
return cur->val;
}
2、头部插入节点
创造一个新的节点,将该节点插入到链表的头部,作为头节点。
注意:先将新节点指向原来的头节点,再将虚拟头节点指向新节点!!!!
//2.头部插入节点
void addAtHead(int val)
{
LinkedNode* newnode=new LinkedNode(val);
newnode->next=_dummyHead->next;
_dummyHead->next=newnode;
size++;
}
3、尾部插入节点
如何找到尾部节点;cur->next=NULL的话,此时,cur就是尾部节点,将cur->next指向新节点即可。
//3.尾部插入节点
void addAtTail(int val)
{
LinkedNode* newnode=new LinkNode(val);
LinkedNode* cur=_dummyHead;
while(cur->next!=NULL)
{
cur=cur->next;
}
cur->next=newnode;
size++;
}
4、第n个节点前插入节点
先找到第N个节点,cur->next指向第n个节点,cur指向第n-1个节点,然后新节点指向cur->next,cur指向新节点
//4.在n个节点前插入节点
void addAtIndex(int index,int val)
{
if(index>size)
{
return;
}
LinkedNode* cur=_dummyHead;
LinkedNode* newnode=new LinkedNode(val);//创造一个新节点并赋予val
while(index)//在这里必须让cur指向第n-1个节点 如果cur指向了第n个节点 将新节点插入时 第n-1个节点没做记录
{
cur=cur->next;
index--;
}
newnode->next=cur->next;
cur->next=newnode;
size++;
}
5、删除第n个节点
先找到第N个节点,cur->next指向第n个节点,cur指向第n-1个节点,将cur指向第n+1节点,释放第n个节点的内存空间
//5.删除第n个节点
void deleteAtIndex(int index)
{
if(index<0||index>=size)
{
return;
}
LinkedNode* cur=_dummyHead;
while(index--)
{
cur=cur->next;
}
LinkedNode *temp=cur->next;
cur->next=cur->next->next;
delete temp;
temp=nullptr;
size--;
}
206.反转链表
文章链接:代码随想录 (programmercarl.com)
视频链接:帮你拿下反转链表 | LeetCode:206.反转链表 | 双指针法 | 递归法_哔哩哔哩_bilibili
有两种方法
1、双指针
cur指向头节点,pre指向cur的前一个节点即为空节点,临时指针指向cur->next
反转操作:
temp=cur->next
cur->next=pre
pre=cur
cur=temp
返回新链表的头节点pre
注意:当cur为空指针的时候,即为遍历结束
2、递归 一一对应双指针