Sorting algorithms - merge sort

The basic idea

The basic idea is to merge sort: first a [0..n-1] as a sorted list of length n 1, adjacent k (k≥2) ordered pairs merge sub-list, to give n / k of length k of ordered sub-table; then continue the ordered merge sub-list, get n / k2 of length k2 of ordered sub-table, so repeatedly continues, to give a final length n the ordered list.

If k = 2, i.e. carried out in two merged ordered adjacent to the sub-tables, referred way merge sort. When k> 2, i.e., merge operation is performed a plurality of ordered sub-table in an adjacent, it is called the merge sort multiplexer.

 For example :

2,5,1,7,10,6,9,4,3,8 sequence {} for which the ordering process from the bottom up as shown below, within the square brackets is an ordered FIG sequence.

 

  Cycle log2n times, length sequentially capturing 1,2, ..., log2n. Each time, perform the following steps:

  ① decomposition: the original sequence into several sub-length sequence of length.

  ② solve the sub-problems: two adjacent sub-sequence call Merge algorithm combined into an ordered sequence.

  ③ combined: because the entire sequence stored in the array A, a sorting process is carried out in situ, the merging step no action.

Top-down ordering process shown below

  ① Decomposition: The sequence a [low..high] into two, i.e., seek mid = (low + high) / 2; recursively two subsequences a [low..mid] and a [mid + 1 .. high] continue to carry out decomposition. Termination condition which is a subsequence of length 1 (sub-table as a table element must be ordered).

  ② combined: and decomposition contrast, the two sub-sorted sequence a [low..mid] and a [mid + 1..high] merged into an ordered sequence of a [low..high].

 Algorithm code

 1 //对区间a[low..mid]和区间a[mid+1..high]进行排序
 2 void Merge(int a[], int low, int mid, int high)
 3 {
 4     int i = low, j = mid + 1;
 5     int k = 0;
 6     int *temp = (int *)malloc((high - low + 1) * sizeof(int));
 7     while (i <= mid && j <= high)
 8         if (a[i] <= a[j]) //将第1子表中的元素放入temp中
 9         {
10             temp[k] = a[i];
11             i++;
12             k++;
13         }
14         else //将第2子表中的元素放入temp中
15         {
16             temp[k] = a[j];
17             j++;
18             k++;
19         }
20     while (i <= mid) //将第1子表余下部分复制到temp
21     {
22         temp[k] = a[i];
23         i++;
24         k++;
25     }
26     while (j <= high) //将第2子表余下部分复制到temp
27     {
28         temp[k] = a[j];
29         j++;
30         k++;
31     }
32     for (k = 0, i = low; i <= high; k++, i++) //将temp复制回a中对应的位置
33         a[i] = temp[k];
34     free(temp); //释放temp所占内存空间
35 }

 自底向上的二路归并排序算法

 1 void MergePass(int a[], int length, int n) //一趟二路归并排序
 2 {
 3     int i;
 4 
 5     for (i = 0; i + 2 * length - 1 < n; i = i + 2 * length) //归并length长的两相邻子表
 6     {
 7         Merge(a, i, i + length - 1, i + 2 * length - 1);
 8     }
 9 
10     if (i + length - 1 < n) //余下两个子表,后者长度小于length
11     {
12         Merge(a, i, i + length - 1, n - 1); //归并这两个子表
13     }
14 }
15 
16 void MergeSort(int arr[], int n) //二路归并算法
17 {
18     for (int length = 1; length < n; length = 2 * length)
19     {
20         MergePass(arr, length, n);
21     }
22 }

 自顶向下的二路归并排序算法

 1 void MergeSort(int a[], int low, int high)
 2 //二路归并算法
 3 {
 4     int mid;
 5     if (low < high) //子序列有两个或以上元素
 6     {
 7         mid = (low + high) / 2;          //取中间位置
 8         MergeSort2(a, low, mid);      //对a[low..mid]子序列排序
 9         MergeSort2(a, mid + 1, high); //对a[mid+1..high]子序列排序
10         Merge(a, low, mid, high);     //将两子序列合并,见前面的算法
11     }
12 }

 算法分析

 对于上述二路归并排序算法,当有n个元素时,需要log2n趟归并,每一趟归并,其元素比较次数不超过n-1,元素移动次数都是n,因此归并排序的时间复杂度为O(nlog2n)。

 

Guess you like

Origin www.cnblogs.com/WindSun/p/11360870.html