开开心心学链表1(链表题总结)

目录

1、二进制链表转整数

2、删除链表中的节点

3、移除链表元素

 4、合并有序链表

5、链表的中间节点

6、删除链表中的重复元素

写在最后


1、二进制链表转整数

原题链接:1290. 二进制链表转整数 - 力扣(LeetCode) (leetcode-cn.com)

思路:逐个节点进行转换,如果为1则相加,为0判断下一个,所有数据相加即为十进制数。

代码如下:

int getDecimalValue(struct ListNode* head){
    struct ListNode *p=head;
    int sum=0;
    while(p){
        sum+=p->val;
        p=p->next;
        if(p)
            sum<<=1;//左移,用来将一个数的各二进制位全部左移1位,右补0
    }
    return sum;
}

2、删除链表中的节点

原题链接:237. 删除链表中的节点 - 力扣(LeetCode) (leetcode-cn.com)

思路:将下一个节点的数据拷贝到需要删除节点。

代码如下:

void deleteNode(struct ListNode* node) {
    node->val=node->next->val;
    node->next=node->next->next;
}

3、移除链表元素

原题链接:203. 移除链表元素 - 力扣(LeetCode) (leetcode-cn.com)

 思路:将所需移除的元素节点的指针域指向下一个节点,若该节点在链表尾部,则直接将指针域指向NULL即可。

代码如下:

法一:

struct ListNode* removeElements(struct ListNode* head, int val){
    struct ListNode *prev=NULL,*cur=head;//prev为cur的前一个节点
    while(cur)
    {
        if(cur->val==val)
        {
            if(cur==head)//所需移除元素在链表头部时
            {
                head=cur->next;
                cur=head;
            }
            else
            {
                prev->next = cur->next;
                free(cur);
                cur=prev->next;
            }
        }
        else
        {
            prev = cur;
            cur=cur->next;
        }
    }
    return head;
}

法二:

struct ListNode* removeElements(struct ListNode* head, int val){
   while(1)
   {
       if(head==NULL)return NULL;//判断链表是否为空
       if(head->val==val)
       {
           head=head->next;
           continue;
       }//判断头节点
       struct ListNode *cur=head;
       while(cur){
           if(cur->val==val)
           {
               break;
           }
           cur=cur->next;
       }//遍历链表
       if(cur==NULL)return head;
       cur=head;
       while(cur->next->val!=val)
       {
           cur=cur->next;
       }//寻找删除元素
       struct ListNode *q;
       q=cur->next;
       cur->next=q->next;
       free(q);
   }
}

 4、合并有序链表

原题链接:21. 合并两个有序链表 - 力扣(LeetCode) (leetcode-cn.com)

思路:

 代码如下:

struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
    if(l1==NULL){
        return l2;
    }
    if(l2==NULL){
        return l1;
    }//判断是否有空链表,若有则无需合并
    struct ListNode *head=NULL,*tail=NULL;
    while(l1&&l2)
    {
        if(l1->val < l2->val){
            if(head==NULL){
                head=tail=l1;
            }
            else{
                tail->next=l1;
                tail=l1;
            }
            l1=l1->next;
        }
        else{
            if(head==NULL){
                head=tail=l2;
            }
            else{
                tail->next=l2;
                tail=l2;
            }
            l2=l2->next;
        }
    }
//若两个链表其中一个已经到了链表尾部
    if(l1){
        tail->next=l1;
    }
    else{
        tail->next=l2;
    }
    return head;
}

5、链表的中间节点

原题链接:876. 链表的中间结点 - 力扣(LeetCode) (leetcode-cn.com)

 思路:定义两个指针,一个fast,一个slow,slow每次走一个节点,fast一次走两个节点,fast走完的时候slow正好走到链表中间。

代码如下:

struct ListNode* middleNode(struct ListNode* head){
    struct ListNode *slow=head,*fast=head;
    if(head==NULL){
        return NULL;
    }
    while(fast&&fast->next){
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}

6、删除链表中的重复元素

原题链接:83. 删除排序链表中的重复元素 - 力扣(LeetCode) (leetcode-cn.com)

 思路:定义一对快慢指针,若有相同元素,则free掉后面的那个节点。

代码如下:

struct ListNode* deleteDuplicates(struct ListNode* head){
    struct ListNode* cur=head,*prev=NULL;
    if(head==NULL)return NULL;//判读链表是否为空
    if(head!=NULL)
    {
        prev=cur;
        cur=prev->next;
    }//判断前两个节点
//遍历链表
    while(cur){
        if(prev->val==cur->val)
        {
            prev->next=cur->next;
            printf("prev:%p\n",prev);
            free(cur);
            cur=prev->next;
            printf("prev:%p\n",prev);
        }
        else{
            prev=cur;
            cur=cur->next;
        }
    }
    return head;
}

写在最后

以上就是本篇文章全部内容,作者知识水平有限,若有什么错误或者需改进之处希望大家指出,若是你有更好的代码希望能给博主留言,博主希望能在CSDN与各位一起进步,感谢大家观看!

猜你喜欢

转载自blog.csdn.net/qq_61139806/article/details/124413372