1、合并两个有序链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(l1==NULL)//如果链表1为空的话,那么合并后的链表是l2,所以返回l2
{
return l2;
}
if(l2==NULL)
{
return l1;//如果链表2为空的话,那么合并后的链表是l1,所以返回l1
}
struct ListNode *c1 = l1;//定义链表1
struct ListNode *c2 = l2;//定义链表2
struct ListNode *result = NULL;//新链表的第一个结点
struct ListNode *tail = NULL;//新链表的最后一个结点
while(c1!=NULL&&c2!=NULL)//如果两个链表都不为空的话,循环继续
{
if(c1->val<=c2->val)//判断链表1和链表2中的值大小,如果链表1中的数字小于等于链表2中 的数值
{
if(tail!=NULL)//新链表的最后一个结点不为空的话,就尾插
{
tail->next=c1;
tail=c1;
}
else//走到这里,说明新链表的最后一个结点为空
{
result=tail=c1;//新链表最后一个结点为空的话,此时就把链表1赋给新链表
}
c1=c1->next;
}
else//如同上边,只是把c1换成c2就可以
{
if(tail!=NULL)//新链表的最后一个结点不为空的话,就尾插
{
tail->next=c2;
tail=c2;
}
else
{
result=tail=c2;//新链表最后一个结点为空的话
}
c2=c2->next;
}
}
if(c1!=NULL)//走到这里说明c1没有遍历完,剩下的直接尾插即可
{
tail->next=c1;
}
if(c2!=NULL)
{
tail->next=c2;
}
return result;
}
2、链表逆置
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode *current = head;//定义一个用于遍历的指针变量,从头结点开始
struct ListNode *prev = NULL;//定义头结点的前驱结点
while (current != NULL)//开始遍历
{
struct ListNode *next = current->next;//先把它保存起来,防止next指向关系发生变化之后,找不到下一个结点的地址了
current->next = prev;//让当前指针的指向指向他的前一个结点,这样就形成了逆置,注意的是结点只能指向一个地方
prev = current;
current = next;
}
return prev;
}
3、分隔链表
给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。
示例:
输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5
struct ListNode* partition(struct ListNode* head, int x){
struct ListNode* small=NULL;//定义一个用于保存比x小的数的链表
struct ListNode* smallLast=NULL;//小链表的最后一个数(空间)
struct ListNode* big=NULL;//定义一个用于保存比x大的链表
struct ListNode* bigLast=NULL;//大链表的最后一个数(空间)
struct ListNode* cur=head;//用于遍历
while(cur!=NULL)//遍历整个原始链表
{
if(cur->val<x)//如果小于x的
{//以下为链表的尾插,尾插就要分两种情况
if(small==NULL)//如果小链表为空
{
small=smallLast=cur;
}
else//如果不为空
{
smallLast->next=cur;
smallLast=cur;//最后一个值发生改变,需要更新,这里小编也很容易忘记呢
}
}
else//以下代码同上,只不过把小链表换成大链表就可以啦
{
if(big==NULL)
{
big=bigLast=cur;
}
else
{
bigLast->next=cur;
bigLast=cur;//最后一个值发生改变,需要更新
}
}
cur=cur->next;//链表能走起来的条件
}
//以下小细节也不容忽视哈
if(smallLast!=NULL)
{
//如果比x小的链表有结点,则把两个链表连起来
smallLast->next=big;
}
if(bigLast!=NULL)
{
//如果比x大的链表有结点,则最后一个结点->next=NULL
bigLast->next=NULL;
}
if(smallLast!=NULL)
{
//有小链表从小的返回
return small;
}
else
{//否则从大的返回
return big;
}
}