Linked list sorting problem

Posted by phprocky on Sat, 15 Jan 2022 01:42:07 +0100

Problem expression

problem analysis

The problem itself is easy to understand. Here are two solutions. The key to the problem of the linked list is to pay attention to the pointing between nodes. In addition, pay attention to each node, such as virtual head node, current node, previous node, next node, etc. the memory distribution of the linked list is scattered, and the nodes are connected by pointers.

  1. Ignore all pointers, store all nodes, and then sort all nodes according to node values. Here, you need to define the node sorting function, and then reconnect the sorted nodes. This method feels relatively simple. In fact, I have a question here. If this method is used, will the pointer originally connected to the node automatically release the occupied memory resources?
  2. The idea of merging and sorting: first find the intermediate node of the linked list. Here, parity should be considered when finding the intermediate node. There are two ways; Then start to divide the linked list according to the intermediate node until there is only one element, which has been sorted; Then start merging. Pay attention to the termination conditions during recursive divide and conquer. In addition, when merging, as long as any node in the linked list remains, it is OK to directly connect the remaining header nodes, and the array needs a while loop to put the elements into the auxiliary array one by one.

Let's talk about custom sorting first

sort function

#include<algorithm>
sort(fisrt,last,cmp)//Fisrt and last are subscripts

Note that the compare function is written outside the class or defined as a static function
std::sort requires a function object or a static / global function pointer. Non static member function pointers cannot be passed directly to std::sort.

static bool cmp(const T&a,const T&b){//T is the template
	return a<b
}

If you want to be in ascending order, define that when a < B, return true;
If you want to reduce the order, you must return true when a > B;

The problem of finding the middle node of the linked list

If the linked list is odd, there is no problem. There must be one intermediate node. If the linked list nodes are even, there are two ways to write whether to go to the first or second node in the middle.
If the acquisition is the first node in the middle:
It is suggested to make a draft when making a question, clarify your ideas, and then start making a question.

ListNode*mid(ListNode*node){
	ListNode*fast=node->next;//node here cannot be empty
	ListNode*slow=node;
	while(fast&&fast->next){
		fast=fast->next->next;
		slow=slow->next;
	}
	return slow;
}

If the acquisition is the second intermediate node

ListNode*mid(ListNode*node){
	ListNode*fast=node;
	ListNode*slow=node;
	while(fast&&fast->next){
		fast=fast->next->next;
		slow=slow->next;
	}
	return slow;
}

Code representation

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    static bool cmp(ListNode*x,ListNode*y){
        return x->val<y->val;//Custom sorting method
    }
    ListNode* sortList(ListNode* head) {
        if(head==nullptr)return head;
        ListNode*dummy=new ListNode(-1);
        dummy->next=head;
        //Put the linked list in the array, a position is a collection, and load the corresponding type of data
        //The idea of sorting arrays is relatively simple
        vector<ListNode*>ans;
        while(dummy->next){
            ans.push_back(dummy->next);
            dummy=dummy->next;
        }
        sort(ans.begin(),ans.end(),cmp);//
        int n=ans.size();
        ListNode*node=new ListNode(0);
        node->next=ans[0];
        ListNode*root=node;
        for(int i=0;i<n;i++){
            node->next=ans[i];
            node=node->next;
        }
        node->next=nullptr;
        return root->next;
    }
};

Complexity

Time complexity: O(nlog ⁡ n), where n is the length of the linked list.

Space complexity: O(⁡ n), number of linked list nodes.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    //The idea of merging and sorting is to divide first and then merge

    ListNode* sortList(ListNode* head) {
    	if(head==nullptr||head->next==nullptr)return head;
        //Find the midpoint
        ListNode*m=mid(head);
        ListNode*l=sortList(head);
        ListNode*r=sortList(m);
        return mergeTwoLists(l,r);
    }
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        //Virtual head node
        ListNode*node=new ListNode(-1);//Create virtual header node
        auto res=node;//Node to return
        //The idea of merging and sorting
        while(l1&&l2){
            if(l1->val<=l2->val){
                node->next=l1;
                l1=l1->next;//Don't forget to update the linked list node
            }
            else{
                node->next=l2;
                l2=l2->next;
            }
            node=node->next;
        }
        if(l1)node->next=l1;
        else if(l2)node->next=l2;
        return res->next;
    }
    ListNode*mid(ListNode*head){
        ListNode*fast=head->next;
        ListNode*slow=head;
        //auto pre=slow;
        while(fast&&fast->next){
            //pre=slow;
            fast=fast->next->next;
            slow=slow->next;
        }
        //pre->next=nullptr;
        ListNode*head1=slow->next;
        slow->next=nullptr;
       // return slow;
       return head1;
    }
};

Complexity

Time complexity: O(nlog ⁡ n), where n is the length of the linked list.

Space complexity: the O(log ⁡ n) space complexity is mainly the stack space occupied by the recursive tree.

Topics: Algorithm data structure leetcode linked list pointer