[C language brush questions] Merge two ordered linked lists & reverse linked lists

Event address: CSDN 21-day learning challenge

Leetcode21 - Merge two ordered linked lists

topic description

Merge two ascending lists into a new ascending list and return. The new linked list is formed by splicing all the nodes of the given two linked lists.

Example 1:
**Input: **l1 = [1,2,4], l2 = [1,3,4] Output: [1,1,2,3,4,4]

image.png

Example 2:
**Input:**l1 = [ ], l2 = [ ] Output: [ ]

Example 3:
**Input:**l1 = [ ], l2 = [0] Output: [0]

hint:

  • The range of the number of nodes of the two linked lists is [0, 50]
  • -100 <= Node.val <= 100
  • Both l1 and l2 are in non- decreasing order

core code pattern

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
    
    

}

Idea analysis and code implementation (C language)

The idea is actually very simple. Here, the sentinel node is used as the head node of the new linked list, and two pointers are used to compare the nodes in the two linked lists with each other. The smaller one is inserted first and the last is inserted into the new linked list. There will always be a linked list first. After inserting, the linked list that has not been inserted inserts the remaining nodes into the new linked list at one time. There are some points to pay attention to. First, the sentinel node is created, and the guard pointer is defined to point to the sentinel node. At this time, the next pointer of the sentinel node should be initialized to NULL immediately, otherwise there is a potential risk of a wild pointer. Define two pointers cur1 and cur2 corresponding to the list1 linked list and list2 linked list respectively, the condition of the while loop should be cur1&&cur2, why? In this case, as long as there is a linked list inserted first, it will immediately jump out of the loop. After the loop ends, according to which linked list has not been inserted, all the remaining nodes are tail-inserted into the new linked list. The auxiliary node we use here - the sentinel node is not provided in the title, we should release it at the end, but before releasing it, we must first take out the content of the next pointer of the sentinel node and return it as the head pointer.

image.png
Code

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
    
    
    struct ListNode* cur1 = list1;
    struct ListNode* cur2 = list2;
    struct ListNode* guard = (struct ListNode*)malloc(sizeof(struct ListNode));
    guard->next = NULL;
    struct ListNode* tail = guard;
    
    while(cur1 && cur2)
    {
    
    
        if(cur1->val > cur2->val)
        {
    
    
            tail->next = cur2;
            tail = tail->next;
            cur2 = cur2->next;
        }
        else
        {
    
    
            tail->next = cur1;
            tail = tail->next;
            cur1 = cur1->next;
        }
    }

    if(cur1)
        tail->next = cur1;
    if(cur2)
        tail->next = cur2;

    struct ListNode* head = guard->next;
    free(guard);
    return head;
}

Leetcode206 - reverse linked list

topic description

Given the head node head of the singly linked list, please reverse the linked list and return the reversed linked list.

Link : Leetcode206

example

Example 1:
**Input: **head = [1,2,3,4,5] Output: [5,4,3,2,1]

image.png

Example 2:
**Input: **head = [1,2] Output: [2,1]

image.png

Example 3:
**Input: **head = [] Output: []

hint:

  • The range of the number of nodes in the linked list is [0, 5000]
  • -5000 <= Node.val <= 5000

core code pattern

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head)
{
    
    
    
}

Idea analysis and code implementation (C language)

1. New linked list head insertion method

In fact, there is a question that is basically the same as this one, except that it requires the use of an array, but here a singly linked list is used. Ideas can also be used for reference. You might as well create a new linked list. However, compared with arrays, there is no need to create new nodes here, but to modify the pointing relationship between nodes. Define a new head pointer newHead, define a cur pointer to find the current node, and find the next pointer to the next node. As long as cur does not point to NULL, put the node pointed by cur into the new linked list. How to put it? Give the content of newHead to the next pointer of cur pointing to the node, let it point to what newHead originally pointed to, and then give the address of the node pointed to by cur to newHead, let newHead point to the node, but pay attention to before performing these operations Put the value of cur->next into next, and put the value of next into cur after execution. In fact, it is to insert the original nodes into the new linked list one by one from front to back.
image.png
Code

struct ListNode* reverseList(struct ListNode* head)
{
    
    
    struct ListNode* cur = head;
    struct ListNode* newHead = NULL;

    while(cur)
    {
    
    
        struct ListNode* next = cur->next;
        cur->next = newHead;
        newHead = cur;
        cur = next;
    }

    return newHead;
}

2. Three pointer inversion method

Have you ever thought about such a method, since the linked list is connected through pointers, can’t the pointer pointing relationship be reversed to achieve reversal? Use three pointers to point to the previous node, the current node and the next node respectively. For a node (prev, cur, next), as long as the point of cur is not NULL, it is said that there is still a node that has not been reversed, and the address of the previous node is assigned to the next pointer of the current node pointed to by cur, so that it Point to the previous node, and then move the three pointers backward one bit, and keep looping until cur points to NULL. The head node of the reversed new linked list is pointed to by prev, just return to prev.
image.png
Code

struct ListNode* reverseList(struct ListNode* head)
{
    
    
    struct ListNode* prev = NULL;
    struct ListNode* cur = head;
    struct ListNode* next = NULL;

    while(cur)
    {
    
    
        next = cur->next;
        cur->next = prev;
        prev = cur;
        cur = next;
    }
    return prev;
}

insert image description here

Guess you like

Origin blog.csdn.net/weixin_61561736/article/details/126283021
Recommended