目录
一、删除链表中等于val值的所有节点
思路一
就是将链表遍历一遍,对比,并将与val相同的链表删除。
删除的具体步骤:1、将待删节点前一个指向待删节点后一个。2、然后释放val节点 。
我们通过双指针的方式实现:
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode *cur=head,*prev=NULL;
while(cur)
{
if(cur->val==val)
{
//当删除头节点时
if(cur==head)
{
head=head->next;
free(cur);
cur=head;
}
else
{
prev->next=cur->next;
free(cur);
cur=prev->next;
}
}
//保持两个指针一前一后
else
{
prev=cur;
cur=cur->next;
}
}
return head;
}
思路二
创建一个新的头结点,然后通过一个cur指针扫描链表,将不等于val的节点尾插到phead后面。如下图
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode *newhead=(struct ListNode *)malloc(sizeof(struct ListNode));
newhead->next=NULL;
struct ListNode *cur=head,*del=NULL,*tail=newhead;
while(cur)
{
if(cur->val!=val)
{
tail->next=cur;
cur=cur->next;
tail=tail->next;
}
else
{
del=cur;
cur=cur->next;
free(del);
}
}
if(tail)//防止传入空链表导致
越界
tail->next=NULL;
return newhead->next;
}
二、反转链表
思路一
简简单单的对原链表进行头插
将原链表一个个头插在newhead节点后:
以此类推
struct ListNode* reverseList(struct ListNode* head){
struct ListNode *cur=head,*next=NULL,* newhead=(struct ListNode *)malloc(sizeof(struct ListNode));
newhead->next=NULL;
while(cur)
{
newhead->next=cur;
cur=cur->next;
newhead->next->next=next;
next=newhead->next;
}
return newhead->next;
}
思路二
将原链表逆序。
我们需要三个指针,少一个都不行,第一步:
第二步:
以此类推,知道cur=NULL
struct ListNode* reverseList(struct ListNode* head){
struct ListNode * prev,*cur,*next=NULL;
prev=NULL;
cur=head;
next=NULL;
while(cur)
{
next=cur->next;
cur->next=prev;
//迭代
prev=cur;
cur=next;
}
return prev;
}
三、合并有序链表
思路:
将两个链表取小值尾插入下面的头节点。
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
struct ListNode *head=(struct ListNide *)malloc(sizeof(struct ListNode));
struct ListNode *tail=head;
while(list1&&list2)
{
//判断大小+尾接
if(list1->val<=list2->val)
{
tail->next=list1;
list1=list1->next;
}
else
{
tail->next=list2;
list2=list2->next;
}
tail=tail->next;
}
//将剩下的链表一起接上
if(list1==NULL)
{
tail->next=list2;
}
if(list2==NULL)
{
tail->next=list1;
}
return head->next;
}
下一期还会有其他几道金典链表oj