单链表OJ(2)

这篇博客介绍了如何在C语言中处理链表问题,包括找到链表的中间节点和倒数第K个节点。提供了两种思路:先遍历计算总节点数和使用快慢指针。还讲述了合并两个有序链表的方法,采用取小尾插策略。每种思路都附带了相应的实现代码。
摘要由CSDN通过智能技术生成

目录

 链表的中间节点

 思路1:先遍历一遍算出总的节点数量

实现代码

思路2:快慢指针

 实现代码

 链表中倒数第K个节点

​ 思路1:倒数第K个既为正数的链表长度(n)-k个 

 实现代码

 思路二:快慢指针

实现代码

 合并两个有序链表

 思路:取小尾插

 实现代码

 链表的中间节点

力扣

 思路1:先遍历一遍算出总的节点数量

然后在遍历找 总节点的一半的那个节点(既中间节点)

实现代码

struct ListNode* middleNode(struct ListNode* head){
        int Listlen = 0;
        struct ListNode* cur = head;
        while(cur)//遍历计算出Listlen
        {
            cur = cur->next;
            Listlen++;
        }
        struct ListNode* mid = head;
        int newlen = Listlen/2;

         while(newlen--)
         {
                 mid = mid->next;
           }

       return mid;
}

思路2:快慢指针

快指针走2步,慢指针走1步(只需要遍历一遍链表)

 实现代码

struct ListNode* middleNode(struct ListNode* head){
    if(head->next == NULL)
    return head;
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast && fast->next)//偶数,奇数 循环终止条件(为NULL)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

 链表中倒数第K个节点

链表中倒数第k个结点_牛客题霸_牛客网

 思路1:倒数第K个既为正数的链表长度(n)-k个 

 实现代码

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    if(pListHead == NULL)
        return NULL; 
    struct ListNode* cur = pListHead;
    int Listlen = 0;
    while(cur)
    {
        cur = cur->next;
        Listlen++; 
    } 
    int n = Listlen-k;
    if(n < 0)
        return NULL;
    struct ListNode* find = pListHead;
    while(n--)
    {
        find = find->next;  
    }
    return find;
}

 思路二:快慢指针

先让快指针走K步,然后快慢指针一起走

实现代码

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    struct ListNode* fast = pListHead;
    struct ListNode* slow = pListHead;
    //先让fast走k步
    int n = 0;
    while(pListHead)
    {
        pListHead = pListHead->next;
        n++;    
    }
    if(k > n)//倒数第K个大于链表长度时,直接返回
        return NULL;
    while(k--)
    {
        fast = fast->next;
    }
    while(fast)
    {
        fast = fast->next;
        slow = slow->next;
    }
    return slow;
    // write code here
}

 合并两个有序链表

力扣

 思路:取小尾插

创建一个头节点,去小的尾插上去

 实现代码

//创建一个带头节点
        struct ListNode* head = NULL;
        struct ListNode*tail =NULL;
        tail=head =(struct ListNode*)malloc(sizeof(struct ListNode));
        tail->next = NULL; 
        while(l1 && l2)//有一个为空循环就结束
        {
            if(l1->val < l2->val)//取小的尾插
             {
               tail->next = l1;
               l1 = l1->next; 
             }
             else
             {
                tail->next = l2;
               l2 = l2->next;
             }
              tail = tail->next;
        }
        //出循环可能是l1或者l2 为空

     if(l1 == NULL)//l2比l1长 l1为空把l2剩余部分尾插上去
        {
            tail->next = l2;
        } 
     if(l2 == NULL)
       {
           tail->next = l1;
       } 
       
        struct ListNode* newhead = head;
        newhead = newhead->next;
        free(head);
       
        return newhead;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值