归并排序

先说一下,这个归并排序(版本一)是我自己的一些想法。简单地浏览了一下书本(《算法:C语言实现》(第三版)),实现方法并不一致。

但是这个算法我测试了一下,还行。

归并排序:分治法的思路。把一个待排序的数组(arr)分成两半(arrA和arrB)进行归并排序。在归并排序的过程中,arrA再分成两半……这个过程直到子数组无可再分。然后就回溯(应该是这么用这个名词),分别这些一对一对的细小的子数组进行插入排序……当这个过程回溯到arr的时候,由于arrA和arrB都已经是有序的子数组了,对arr的插入排序的工作量就相当小了。

版本一:

 1 void
 2 InsertSort(int arr[], int left, int right)
 3 {
 4     for (int i = left+1; i <= right; i++) {
 5         int tmp = arr[i];
 6         for (int j = i-1; j >= 0 && arr[j] > tmp; j--) {
 7             arr[j+1] = arr[j];
 8             arr[j] = tmp;
 9         }
10     }
11 }
12 
13 void
14 MergeSort(int arr[], int left, int right)
15 {
16     if (left == right) {
17         return;
18     }
19     
20     int middle = (left + right) / 2;
21     
22     MergeSort(arr, left, middle);
23     MergeSort(arr, middle+1, right);
24     
25     InsertSort(arr, left, right);
26 }

 版本二:读了Mark Allen Weiss的《数据结构与算法分析——C语言描述》(第二版),知道自己写的归并排序有分治的思想,但是在时间复杂度上其实还是维持插入排序的程度,是O(n^2),达不到O(nlogn)的程度。根据书本的知识,有了版本二的算法。

 1 // 作合并操作 
 2 void
 3 Merge(int arr[], int tmpArr[], int leftPos, int rightPos, int rightEnd)
 4 {
 5     int leftEnd = rightPos - 1;
 6     int len = rightEnd - leftPos + 1;
 7     int tmpPos = leftPos;
 8     
 9     while (leftPos <= leftEnd && rightPos <= rightEnd) {
10         if (arr[leftPos] < arr[rightPos]) {
11             tmpArr[tmpPos++] = arr[leftPos++];
12         } else {
13             tmpArr[tmpPos++] = arr[rightPos++];
14         }
15     }
16     
17     while (leftPos <= leftEnd) {
18         tmpArr[tmpPos++] = arr[leftPos++];
19     }
20     while (rightPos <= rightEnd) {
21         tmpArr[tmpPos++] = arr[rightPos++];
22     }
23     
24     for (int i = 0; i < len; i++, rightEnd--) {
25         arr[rightEnd] = tmpArr[rightEnd];
26     }
27 }
28 
29 
30 // 归并排序 
31 void
32 MergeSort(int arr[], int tmpArr[], int left, int right)
33 {
34     if (left < right) {
35         
36         int middle = (left + right) / 2;
37         
38         MergeSort(arr, tmpArr, left, middle);
39         MergeSort(arr, tmpArr, middle+1, right);
40         
41         Merge(arr, tmpArr, left, middle+1, right);
42     }
43 }

 

posted @ 2014-10-26 21:43  nipan  阅读(217)  评论(0编辑  收藏  举报