单链表OJ(2)

目录

 链表的中间节点

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

实现代码

思路2:快慢指针

 实现代码

 链表中倒数第K个节点

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

 实现代码

 思路二:快慢指针

实现代码

 合并两个有序链表

 思路:取小尾插

 实现代码

 链表的中间节点

力扣

单链表OJ(2)_第1张图片

 思路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步(只需要遍历一遍链表)

单链表OJ(2)_第2张图片

 实现代码

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个结点_牛客题霸_牛客网

单链表OJ(2)_第3张图片 思路1:倒数第K个既为正数的链表长度(n)-k个 

单链表OJ(2)_第4张图片

 实现代码

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步,然后快慢指针一起走

单链表OJ(2)_第5张图片

实现代码

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
}

 合并两个有序链表

力扣

单链表OJ(2)_第6张图片

 思路:取小尾插

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

单链表OJ(2)_第7张图片

 实现代码

//创建一个带头节点
        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;
}

你可能感兴趣的:(链表,c语言,算法)