[Algorithm]--merge sort (merge sort)

Source: Internet
Author: User

Merge sort is similar to the idea of quick sort: Divide the data to be sorted into two parts, continue to recursively merge the two sub-parts, and then combine the two sub-parts that are already ordered, and finally complete the sort. Both the time complexity and the fast sort are O (Nlogn), but the merge sort is indirectly using the secondary space stack in addition to the recursive invocation, and additional O (n) space is required for temporary storage. Merging from this angle is slightly inferior to the quick sort, but the merge sort is a stable sort algorithm, and the quick sort is not.

The so-called stable ordering , which means that for multiple elements with the same value, the order of precedence remains unchanged. For basic data types, a sort algorithm is stable and has little impact, but for a struct array, it is important to stabilize the ordering. For example, the student struct is sorted in a non-descending order by keyword score:

A structure Data definitiontypedef struct __student{char name[16];int score;} student;//Array of Studentsname:  A      B     C     dscore:    70Stable sort in ascending Order:name:  B      D     C     ascore:    80Unstable sort in ascending order:name :  D      B     C     ascore:    80

A stable sort ensures that B is always preceded by D, but not stable, and cannot be guaranteed.

1) Merge sort of array

The idea of merging sort is actually a kind of divide-and-conquer method, which divides the data into two parts, sorts the two parts separately, and then merges the two parts. The following is an example of a non-descending sort:

Split arr[] into parts [Begin,mid), [mid,end]//and using Merge_core to merge this, parts//total time O (Nlogn) v OID merge_sort (int arr[], int begin, int end) {int mid = (begin+end) >>1;if (begin >= End) Return;merge_sort (arr,be GIN,MID); Merge_sort (arr,mid,end); Merge_core (arr,begin,mid,end);} Time O (LOGN)

Where arr[] is the array to be sorted, and for an array of length N, call Merge_sort (arr,0,n) directly;

The merge sort is divided into two sections, first divided into two parts, then each part sorted and finally merged. Of course, it can be divided into three parts or other, but it is usually divided into two parts, so it is called two-way merging. Merge_core can combine two ordered arrays into one, specifically:

/* Merge Core:combine Parts which is sorted in ascending order * arr[]: ..., 1, 4, 8, 2, 3, 7, 9, ... *      begin__|        |__mid      |__end * part1:1, 4, 8       part2:2, 3, 7, 9  * * Combination: * part1:[1]            [4]       [8] * Part2: |< C7/>[2]  [3]   |   [7]   |   [9] * | | | | | | |    * tmp  : [1]  [2]  [3]  [4]  [7]  [ 8]  [9] * @ Last, Copyback tmp to arr[begin,end) * */

The premise of merging is that two arrays are already ordered . The code is:

void Merge_core (int arr[], int begin, int mid, int end) {int I=begin, j=mid, K=0;int *tmp = (int*) malloc (sizeof (int) * (end-b Egin)); for (; I<mid && j<end; tmp[k++]= (arr[i]<arr[j]?arr[i++]:arr[j++])), for (; i<mid; tmp[k++]= arr[i++]); for (; j<end; tmp[k++]=arr[j++]); for (I=begin, k=0; i<end; arr[i++]=tmp[k++]); free (TMP);} Time O (n), Space O (n)

6th, 72 lines, append the remainder to tmp[], and then write tmp[] back to arr[]. Therefore, using merge ordering for arrays requires a secondary space O (n). Because it is the tail call Merge_core, of course, it can be written to the tail of merge_sort, here for the sake of clarity, it is divided into two parts of writing.

2) Merge sort of linked list

In fact, the merge sort is more suitable for sorting the linked list , because there is no need for additional secondary space storage when merging two linked lists, and there is no need to copy the data and move the pointer directly. The only inconvenience is that you need to find the middle node of the list every time and then split the list into two parts. Looking for intermediate nodes, you can define two pointers fast and mid,fast each move two steps, mid each move one step, when fast to the end of the linked list, mid is now in the middle of the list (regardless of the parity case):

Merge sort for single list as ascending order//single list node definetypedef struct __listnode{int val;struct __listn Ode *next;} listnode;//Merge sort for single list without head Nodelistnode *merge_sort (ListNode *head) {if (head==null) return null;l Istnode *fast, *mid, h;//find mid node between head and ENDfor (H.next=head, fast=mid=&h; fast;) {mid = Mid->next;f AST = Fast->next;fast = (fast fast->next:null);} Fast = Mid->next;mid->next = null;//Cut down mid part from head listmid = Fast;head = Merge_sort (head); mid = Merge_ Sort (mid); return Merge_core (Head,mid);}

Note that after you find the middle node of the list, be sure to point it to null to ensure that the linked list is actually split into two parts. Then merge the two linked list head with mid. Because the linked header nodes may be modified after merging, the new list header nodes are returned. Here is the merge operation:

Merge single list without head node (ascending order) ListNode *merge_core (ListNode *i, ListNode *j) {ListNode H, *p;for (p=&h; i && J; p=p->next) {if (I->val < j->val) {P->next = I;i = I->next;} Else{p->next = J;j = J->next;}} P->next = (I? i:null);p->next = (J. j:null); return h.next;}

When a linked list is merged, it is not necessary to direct the end of the list p->next to the remaining I or J, as in arrays, to complete the merge. As you can see, merge sort is more appropriate for sorting linked lists, and quick sorting is appropriate for array sorting.

Note: All the code in this article can be found in the sort/mergesort.c in Https://git.oschina.net/eudiwffe/codingstudy.

[Algorithm]--merge sort (merge sort)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.