day9--linked list (public nodes, addition, sorting)

The first common node of the two linked lists

double pointer

Use two pointers p and q to point to the head nodes of the two linked lists head1 and head2 respectively, and then traverse node by node at the same time, when p reaches the end of the linked list head1, relocate to the head node of the linked list head2; when q arrives At the end of the linked list head2, relocate to the head node of the linked list head1. In this way, when p and q meet, the node pointed to is the first common node. Let the length from head1 to the common node be a, and the length from head2 to the common node be b, then a+b=b+a, after splicing, the lengths from head1 and 2 to the common node are equal

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        ListNode *p=pHead1, *q=pHead2;
		while(p!=q){
			if(p==NULL) p=pHead2;
			else p=p->next;
			if(q==NULL) q=pHead1;
			else q=q->next;
		}
		return p;
    }
};

Stack: We load the nodes of the linked list into the stack, compare the top nodes, and then traverse the stack to find common nodes.

Linked list length difference: respectively traverse the two linked lists headA and headB, if the pointers are the same, return directly, otherwise, calculate the length difference of the linked list, we use the variable step to calculate the length of the long linked list compared to the short linked list, next, we let The long linked list runs step first, and then the linked lists headA and headB move synchronously to find common nodes.

 Linked list addition (2)

Reverse two linked lists and add 

Add from the beginning after flipping, use an integer variable to record the carry value, use head interpolation to store the result, and finally flip the result

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head1 ListNode类 
     * @param head2 ListNode类 
     * @return ListNode类
     */
    ListNode* addInList(ListNode* head1, ListNode* head2) {
        // write code here
        head1=reverse(head1);
        head2=reverse(head2);
        ListNode *dummy = new ListNode(0);
        ListNode *cur=dummy;
        int jw=0;//进位
        while (head1 || head2 || jw) {
            int sum = jw;
            if(head1){
                sum += head1->val;
                head1=head1->next;
            }
            if(head2){ 
                sum += head2->val;
                head2=head2->next;
            }
            jw = sum /10;
            sum %= 10;
            cur->next=new ListNode(sum);
            cur=cur->next;
        }
        ListNode *res=reverse(dummy->next);//结果翻转
        return res;
    }
    ListNode* reverse(ListNode *head){
        ListNode *pre=NULL, *cur=head;
        while(cur!=NULL){
            ListNode *next=cur->next;
            cur->next=pre;
            pre=cur,cur=next;
        }
        return pre;
    }
};

 Sorting of singly linked list

merge sort

Divide the unordered list into left and right two, recursively decompose, each can be regarded as an ordered list, and then merge the ordered lists in pairs

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

#include <algorithm>
class Solution {
public:
    /**
     * 
     * @param head ListNode类 the head node
     * @return ListNode类
     */
    ListNode* sortInList(ListNode* head) {
        // 归并排序
        if (!head || !head->next) return head;
        ListNode *slow = head, *fast = head;
        while (fast->next && fast->next->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        ListNode *mid = slow->next;//注意1
        slow->next = nullptr;
        ListNode *left = sortInList(head);
        ListNode *right = sortInList(mid);
        return merge(left, right);
    }
    ListNode *merge(ListNode* h1, ListNode* h2){
        ListNode dummy(0),*p = &dummy;
        while(h1 && h2){
            if(h1->val < h2->val){
                p->next=h1;
                h1=h1->next;
            }else{
                p->next=h2;
                h2=h2->next;
            }
            p=p->next;//注意2
        }
        if(h1) p->next=h1;
        if(h2) p->next=h2;
        return dummy.next;
    }
};

quick sort

Find the benchmark: traverse the following nodes: put the smaller ones on the left, and put the larger ones on the right; then merge the left + benchmark + right

// 快速排序函数
ListNode* quickSortList(ListNode* head) {
    if (head == NULL || head->next == NULL) {
        return head;
    }
    // 选择一个基准元素
    ListNode *pivot = head;
    head = head->next;
    pivot->next = NULL;
    // 将链表分成两个部分
    ListNode *left = NULL, *right = NULL;
    while (head != NULL) {
        ListNode *next = head->next;
        if (head->val < pivot->val) {
            head->next = left;
            left = head;
        } else {
            head->next = right;
            right = head;
        }
        head = next;
    }
    // 递归地对左右两个部分进行排序
    left = quickSortList(left);
    right = quickSortList(right);
    // 将左右两个部分和基准元素拼接起来
    if (left == NULL) {
        pivot->next = right;
        return pivot;
    } else {
        ListNode *tail = left;
        while (tail->next != NULL) {
            tail = tail->next;
        }
        tail->next = pivot;
        pivot->next = right;
        return left;
    }
}

Guess you like

Origin blog.csdn.net/qq_54809548/article/details/130933823