归并排序

归并排序采用了分治法的思想,下面给出了非递归实现和递归实现的方法 ,以方便以后使用。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 // begin: 左边子序列的起始下标
 5 // mid  : 右边子序列的起始下标
 6 // end  : 右边子序列的结束元素的下一个位置(子序列不包括end指向的元素)
 7 void mergeArray(int a[], int begin, int mid, int end, int t[])
 8 {
 9     int length = end - begin;// 合并后序列的长度
10     int i = begin, j = mid; // i,j分别指向两个子序列的开始位置
11     int k = 0; // 指示临时数组中下一个数据的写入位置
12 
13     // 合并两个子序列元素
14     while (i < mid && j < end){
15         if (a[i] <= a[j]){
16             t[k++] = a[i++];
17         }else{
18             t[k++] = a[j++];
19         }
20     }
21     // 如果还有没有合入的元素
22     while (i < mid){
23         t[k++] = a[i++];
24     }
25 
26     while (j < end){
27         t[k++] = a[j++];
28     }
29 
30     // 将合并结果重新写入到数组a中
31     for (i = 0; i < length; i++){
32         a[begin + i] = t[i];
33     }
34 }
35 
36 void merge_sort(int a[], int left, int right)
37 {
38     int length = right - left + 1;
39     int *temp = (int*)malloc(length * sizeof(int));// 临时存放合并结果的数组
40     int i, step = 1; // 初始有序子序列步长设置为1
41     
42     // 自底向上进行归并排序
43     while (step < length){
44         for (i = 0; i+2*step < length; i += 2*step){
45             mergeArray(a, i, i+step, i+2*step, temp);
46         }
47 
48         if (i+step < length){
49             mergeArray(a, i, i+step, right+1, temp);
50         }
51 
52         step *= 2;// 子序列长度翻倍
53     }
54 
55     free(temp);
56 }
57 
58 void merge_sort_r(int a[], int left, int right, int t[])
59 {
60     int mid;
61     if (left < right){
62         // 注意,计算mid时很容易写成(right - left)/2可能出现mid<left的情况
63         mid = left + (right - left)/2;
64         merge_sort_r(a, left, mid, t);
65         merge_sort_r(a, mid+1, right, t);
66         mergeArray(a, left, mid+1, right+1, t);
67     }
68 }
69 
70 int main()
71 {
72     int a[] = {7,2,11,5,8,3,4,7,10,9};
73     int *temp = (int*)malloc(10 * sizeof(int));
74     merge_sort_r(a, 0, 9, temp);
75     free(temp);
76     
77     return 0;
78 }

 

posted @ 2015-08-13 09:14  XiaoManon  阅读(250)  评论(0编辑  收藏  举报