1. topic
2. answers
2.1 Quick Sorting
May refer to Quick sort and merge sort The first idea of quick sorting is different from sorting in arrays.
First, we need to take the last element as the principal element, which can be accessed directly in the array, but in a single list, we need to traverse the list first to access the last element.
Secondly, in the array, we can use subscripts to recursively call after dividing the array into left and right parts by using the principal component, but in the linked list, we use the head pointer and the tail pointer to identify the left and right parts. As shown in the figure below, the left half of the head pointer is head, the tail pointer is p1; the right half of the head pointer is p1-next, and the tail pointer is end.
class Solution { public: ListNode* sortList(ListNode* head) { if(head == NULL) return head; Quick_Sort(head, NULL); return head; } void Quick_Sort(ListNode* head, ListNode* end) { if (head != end && head->next != end) { ListNode* ptr = head; while(ptr->next != end) ptr = ptr->next; // Take the last element of the list as the principal element int pivot = ptr->val; ListNode* p1 = head; ListNode* p2 = head; while(p2->next != end) { if(p2->val < pivot) { int temp = p2->val; p2->val = p1->val; p1->val = temp; p1 = p1->next; } p2 = p2->next; } p2->val = p1->val; p1->val = pivot; Quick_Sort(head, p1); // At this point P1 points to pivot, the first half of the list is head ed and the end is p1. Quick_Sort(p1->next, end); // The second half of the list has a head of P1 - > next and a tail of end. } }
2.2 Merge Sort
May refer to Quick sort and merge sort There are three main steps in the merging and sorting thought.
- Find the middle node of the list
- Recursive Sorting of Left and Right Parts
- Merge the sorted two-part list, which we insert into another list because we can't use extra space.
class Solution { public: ListNode* sortList(ListNode* head) { return Merge_Sort(head); } ListNode* Merge_Sort(ListNode* head) { ListNode * mid = Find_Mid(head); if (mid) { ListNode* right_head = mid->next; mid->next = NULL; ListNode* left_head = Merge_Sort(head); right_head = Merge_Sort(right_head); head = Merge_List(left_head, right_head); } return head; } ListNode* Merge_List(ListNode* left_head, ListNode* right_head) { ListNode* l1 = left_head; ListNode* l2 = right_head; if (left_head->val > right_head->val) { l1 = right_head; l2 = left_head; } // l1 points to a linked list with a smaller value for the first node, and then inserts each node in l2 into l1 ListNode* p1 = NULL; ListNode* head = l1; while (l1->next && l2) { if (l1->next->val > l2->val) { p1 = l1->next; l1->next = l2; l2 = l2->next; l1 = l1->next; l1->next = p1; } else { l1 = l1->next; } } if (l2) l1->next = l2; //If there are nodes in l2 that can be inserted directly after l1 return head; } ListNode* Find_Mid(ListNode* head) { if (head == NULL || head->next == NULL) return NULL; ListNode* slow = head; ListNode* fast = head; while (fast->next != NULL && fast->next->next != NULL) { slow = slow->next; fast = fast->next->next; } return slow; } };
For more excitement, please pay attention to "seniusen".