1.移除链表元素
单链表相关经典算法OJ题1:移除链表元素
思路1:遍历原链表,将val节点释放掉
实现代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val)
{
//这个循环可以解决两种情况
//1.空链表
//2.非空链表,而且第一个结点就是要删除的值,还会一直删除到不是val的结点
//比如一个链表是这样的2->2->2->3,假设要删除的数字是2
//走完下面这个循环后
//head就指向3这个结点
while (NULL != head && head->val == val)
{
head = head->next;
}
//
struct ListNode* curr=head;
struct ListNode* prev=NULL;
while(curr!=NULL)
{
if(curr->val!=val)
{
prev=curr;
}
else
{
prev->next=curr->next;
}
curr=curr->next;
}
return head;
思路2:找不为val的节点,尾插到新链表
实现代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val)
{
//创建一个空链表
ListNode* newHead, * newTail;
newHead = newTail = NULL;
//遍历原链表
ListNode* pcur = head;
while (pcur)
{
//找值不为val的节点,尾插到新链表中
if (pcur->val != val)
{
//链表为空
if (newHead == NULL)
{
newHead = newTail = pcur;
}
else
{
//链表不为空
newTail->next = pcur;
newTail = newTail->next;
}
}
pcur = pcur->next;
}
if (newTail)
{
newTail->next = NULL;
}
return newHead;
}
2.反转链表
单链表相关经典算法OJ题2:
反转链表
思路1:双指针法
如果再定义一个新的链表,实现链表元素的反转,其实这是对内存空间的浪费。
其实只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表,如图所示:
之前链表的头节点是元素1, 反转之后头结点就是元素5 ,这里并没有添加或者删除节点,仅仅是改表next指针的方向。
首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。
然后就要开始反转了,首先要把 cur->next 节点用tmp指针保存一下,也就是保存一下这个节点。
为什么要保存一下这个节点呢,因为接下来要改变 cur->next 的指向了,将cur->next 指向pre ,此时已经反转了第一个节点了。
接下来,就是循环走如下代码逻辑了,继续移动pre和cur指针。
最后,cur 指针已经指向了null,循环结束,链表也反转完毕了。 此时我们return pre指针就可以了,pre指针就指向了新的头结点。
实现代码:
// 双指针法:
struct ListNode* reverseList(struct ListNode* head)
{
//保存cur的下一个结点
struct ListNode* temp;
//pre指针指向前一个当前结点的前一个结点
struct ListNode* pre = NULL;
//用head代替cur,也可以再定义一个cur结点指向head。
while(head)
{
//保存下一个结点的位置
temp = head->next;
//翻转操作
head->next = pre;
//更新结点
pre = head;
head = temp;
}
return pre;
}
3.合并两个有序链表
单链表相关经典算法OJ题3:
合并两个有序链表
. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/merge-two-sorted-lists/description/
思路:
首先创建一个结点,然后比较两个链表的数值,将更小的那个结点并入刚创建的结点,以此类推,最后将还有剩余结点的链表介入新链表,注意节点为空等特殊情况的处理即可。
实现代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
//如果list1和list2中有一个为空就直接返回另一个节点
if(list1==NULL)
{
return list2;
}
if(list2==NULL)
{
return list1;
}
//定义l1,l2指针分别指向list1和list2的头节点
ListNode*l1,*l2;
ListNode*newHead,*newTail;
//给新链表开辟一个哨兵位
newHead=newTail=(ListNode*)malloc(sizeof(ListNode));
l1=list1,l2=list2;
while(l1&&l2)
{
if(l1->val<=l2->val)
{
newTail->next=l1;
newTail=newTail->next;
l1=l1->next;
}
else
{
newTail->next=l2;
newTail=newTail->next;
l2=l2->next;
}
}
if(l1)
{
newTail->next=l1;
}
if(l2)
{
newTail->next=l2;
}
//新链表的第一个节点是头结点为无效数据,因此返回头结点的next
return newHead->next;
}
本篇文章只介绍了题目的部分解法。如果本篇有补充的地方,欢迎私信我或在评论区指出,期待与你们共同进步。