排序問題1

本博客的代碼的思想和圖片參考:好大學慕課浙江大學陳越老師、何欽銘老師的《數據結構》算法

 

排序shell

1 排序前提

1.函數的名稱規範編程

void X_Sort ( ElementType A[], int N )數組



2.大多數狀況下,爲簡單起見,討論從小大的整數排序數據結構



3.N是正整數app



4只討論基於比較的排序( >= < 有定義 )ide



5.只討論內部排序函數



6穩定性:任意兩個相等的數據,排序先後的相對位置不發生改變工具



7.沒有一種排序是任何狀況下都表現最好的oop

1 冒泡排序

1.1算法思想

第一趟:比較第一個元素和第二元素,若是第一個元素比第二個元素大,就交換位置,不然就不交換位置;在比較第二元素和第三個元素的大小,若是第二個元素比第三個元素大,交換位置,不然不交換位置;而後接着比較第三個元素和第四個元素…… 直到比較到第N-1個元素和第N個元素。這樣一趟下來,能夠肯定最大的元素在N位置

第二趟:比較第一個元素和第二元素,若是第一個元素比第二個元素大,就交換位置,不然就不交換位置;在比較第二元素和第三個元素的大小,若是第二個元素比第三個元素大,交換位置,不然不交換位置;而後接着比較第三個元素和第四個元素……,直到比較到N-2 N-1個元素。這樣,第二趟下面,第二大的元素能夠肯定在N-1位置。

第三趟……

這樣到第N趟,就能夠吧數組排序完成。

1.2 僞代碼描述

/*

* A method to implement bubble sort.If the bubble sort has no any swap

* operation at one time,indicating the array has been ordered.So we use a

* tag to make it effective

*@param a A integer array need to sort

*@param n The length of the array

*/

voidbubble_sort(elementType a[], int n) {

int i, j, flag;

for (i = n - 1; i >= 0; i--) {

flag = 0;

for (j = 0; j < i; j++) {

if (a[j] > a[j + 1]) {

swap(&a[j], &a[j + 1]);

flag = 1;

}

}

if (flag == 0) {

break;

}

}

}



1.3 算法分析

最好的狀況:若是這個數組自己就是有序的,那麼時間複雜:T=O(N)

最壞的狀況:若是這個數組自己就是逆序的,那麼時間複雜度爲T=O(N^2)

由於只有當前面的元素嚴格的大於後面元素時,纔會交換位置,相對位置不會發生改變,那麼該算法是穩定的。



2 選擇排序

2.1算法思想

選擇排序的前提是保證數組中已有元素是有序的。例如在給數組的第i個元素排序(找合適位置)時,已經保證前面i-1個元素是有序的。

第一趟:當給數組中第一個元素排序時,由於就一個元素,默認就是有序的。

第二趟:當給數組中第二元素排序時,比較(前一個元素)第一個元素是否比他大,若是大,把前一個元素日後面摞一位,而後。

第三趟:給數組中第三個元素排序時,比較前一個元素是否是比他大,比他大,前一個元素向後摞一位。在比較在前面一個元素是否比他大,若是比他大,在吧在前一個元素日後摞一位;若是不比他大,那麼剛纔那個摞的那個空位就就放入該元素。

第四趟……

N



2.2 僞代碼描述

/*

* Implemet insertion sort.

*@param a A integer array need to sort

*@param n The length of the array

*/

voidinsertion_sort(elementType a[], int n) {

int i, j;

elementType temp;

for (i = 1; i < n; i++) {

temp = a[i];

for (j = i; j > 0 && a[j - 1] > temp; j--) {

a[j] = a[j - 1];

}

a[j] = temp;

}


}





2.3 算法分析

最好的狀況:若是這個數組自己就是有序的,那麼時間複雜:T=O(N)

最壞的狀況:若是這個數組自己就是逆序的,那麼時間複雜度爲T=O(N^2)

由於只有當前面的元素嚴格的大於後面元素時,纔會交換位置,相對位置不會發生改變,那麼該算法是穩定的。





3 時間複雜的下界

爲了說明這個問題,我先給出一個例題:

給定初始序列{34, 8, 64, 51,32, 21},冒泡排序和插入排序分別須要多少次元素交換才能完成?

答:冒泡須要9次,選擇排序也須要9次。這是一個巧合嗎?

3.1 引入概念

對於下標i<j,若是A[i]>A[j],則稱(i,j)是一對逆序對(inversion)

問題:序列{34, 8, 64, 51, 32, 21}中有多少逆序對?

(34, 8) (34, 32) (34, 21) (64, 51) (64, 32) (64, 21) (51, 32) (51, 21) (32, 21)

有九個逆序對。

交換兩個相鄰的逆序對正好消去一個逆序對!

插入排序(冒泡排序)的時間複雜度能夠從新定義爲:

T(N,I)=O(N,I).IN個元素中逆序對的個數

——若是須要排序的序列基本有序,則插入排序簡單且高效



3.2 時間複雜度下界

定理:任意N個不一樣元素組成的序列平均具備N ( N - 1 ) / 4 個逆序對。

定理:任何僅以交換相鄰兩元素來排序的算

,其平均時間複雜度爲 ( N^2 )

這意味着:要提升算法效率,咱們必須

1.每次消去不止1個逆序對!

2. 每次交換相隔較遠的2個元素!



4 希爾排序

4.1算法思想

定義增量序列 D M > D M-1 > ... > D 1 = 1

對每一個 D k 進行「D k -間隔」排序 ( k = M, M-1, ... 1 )

注意:「D k -間隔」有序的序列,在執行「D k-1 -間隔」排序後,仍然是「D k -

間隔」有序的。下面用一幅圖片來講明希爾排序的過程

 

 

4.2希爾排序的僞代碼描述

4.2.1基本的希爾排序的僞代碼

/*

* Implement base shell sort

*@param a A integer array need to sort

*@param n The length of the array

*/

voidshell_sort_base(elementType a[], int n) {

int i, j, d;

elementType temp;

for (d = n / 2; d > 0; d = d / 2) {

for (i = d; i < n; i++) {

temp = a[i];

for (j = i; j >= d && a[j - d] > temp; j -= d) {

a[j] = a[j - d];

}

a[j] = temp;

}

}


}



在基本的希爾排序中,咱們的間隔取 n/2 n/4 n/8 … n/2^i … 1

在上面基本的希爾排序中,最壞的時間複雜度T(n)=O(n^2).很糟糕

下面舉一個最壞狀況的例子

4.3 希爾排序的增量序列

 

5 堆排序

5.1 引子

在介紹堆排序以前,咱們先介紹一下選擇排序。

選擇排序的算法思想:第一次從N個元素中選擇一個最小的。放入0位置,第二次從N個元素中選擇第二小的,放入1位置。… 第i次從N個元素選擇第i小的元素放入第i-1位置

下面是選擇排序的僞代碼描述

void Selection_Sort ( ElementType A[], int N )

{

for ( i = 0; i < N; i ++ ) {

MinPosition = ScanForMin( A, i, N–1 );

/* A[i]A[N–1]中找最小元,並將其位置賦給MinPosition */

Swap( A[i], A[MinPosition] );

/* 將未排序部分的最小元換到有序部分的最後位置 */

}

}

對於交換元素的操做,是線性。問題在於從N個元素每次找到最i小的元素。選擇排序比較暴力,他每次都是從N個元素中選擇最小的元素,而後進行交換位置。這樣時間時間複雜度T(N)=O(N^2).咱們若是改進找到最小元的操做?

答案是使用咱們之前學過的工具,最小堆。

5.2 堆排序算法1---利用最小堆

算法思想:把用戶給定的數組調整成一個最小堆,每次從堆中彈出一個最小的元素,使用臨時數組保存,而後在吧臨時數組的元素複製回原數組。

僞代碼描述:

void Heap_Sort ( ElementType A[], int N )

{

BuildHeap(A); /* O(N) */

for ( i=0; i<N; i++ )

TmpA[i] = DeleteMin(A); /* O(logN) */

for ( i=0; i<N; i++ ) /* O(N) */

A[i] = TmpA[i];

}

經過僞代碼咱們能夠看到,此算法的時間複雜的度爲T(N)=O(NlogN),可是他須要開闢一個臨時的數組O(N)來存放已經排序好的元素。並且還修養話費元素複製的時間。

5.3 堆排序算法2---利用最大堆

算法思想:首先吧數組調整成最大堆。把最大堆的第一個元素和最後一個元素調換位置。這樣最大的元素就在原數組的最後。而後吧剩下n-1個元素調整成最大堆。重複上面的操做。這樣每次選出最大的元素。

僞代碼描述:

void Heap_Sort ( ElementType A[], int N )

{

for ( i=N/2-1; i>=0; i-- )/* BuildHeap */

PercDown( A, i, N );

for ( i=N-1; i>0; i-- ) {

Swap( &A[0], &A[i] ); /* DeleteMax */

PercDown( A, 0, i );

}

}



5.3 算法分析

1.定理:堆排序處理N個不一樣元素的隨機排列的平均比較次數是2N logN - O(Nlog logN)

2.雖然堆排序給出最佳平均時間複雜度,但實際效果不如用Sedgewick增量序列的希爾排序。

3.堆排序好處是取出前i個最小的數。



6 歸併排序

6.1有序子列歸併

在介紹歸併排序的算法以前,咱們先來介紹一下「有序子列的歸併」下面經過一張圖片來介紹

 

 

下面是給出有序子列歸併的源代碼

/*

* Merge sub-sequence to original array.

* @param a original <code>elementType</code> array to store the elements

* @param tmpA temporary <code>elementType</code> array to store the temporary elements

* @param l The start index of left sub-sequence

* @param r The start index of left sub-sequence

* @param rightEnd The end index of left sub-sequence

*/

voidmerge(elementType a[], elementType tmpA[], int l, int r, int rightEnd) {

/*

* lefeEnd is the r-1,the sub-sequence is adjacent

*/

int leftEnd = r - 1;

/*

* tmp is the counter of the <code>tmpA</code>

* we should let <code>tmpA</code> index corresponding original array

*/

int tmp = l;

/*

* Record the quantity of the all elements

*/

int numElements = rightEnd - l + 1;

int i;

while (l <= leftEnd && r <= rightEnd) {

if (a[l] <= a[r]) {

tmpA[tmp++] = a[l++];

} else {

tmpA[tmp++] = a[r++];

}

}

while (l <= leftEnd) {

tmpA[tmp++] = a[l++];

}

while (r < rightEnd) {

tmpA[tmp++] = a[r++];

}


/*

* Put <code>tmpA</code> elements into the original array

*/

for (i = 0; i < numElements; i++, rightEnd--) {

a[rightEnd] = tmpA[rightEnd];

}

}




這個代碼的時間複雜度在上面已經說過了,爲T(N)=O(N)

6.2 遞歸算法的遞歸實現

 

這個時間複雜的沒有最好,最壞,平均。不論什麼樣的序列,都是NlogN的時間複雜度。

6.3 遞歸算法中的臨時數組問題

在歸併排序中,咱們使用到一個臨時數組,那麼這個臨時數組在哪裏分配比較合理?

設想一下,若是咱們在merge函數中申請,那會怎麼樣呢。那就會出現,沒調用一次merge函數,咱們須要申請和釋放這樣的一個臨時數組。這樣申請釋放的操做以下圖所示:

這樣會平凡的對內存進行申請和釋放,是很不划算的,並且最後仍是要申請一個和N同樣大學的數組,那麼咱們還不如本身在接口函數中把她直接定義好。以下圖所示:

 

 

雖然咱們在一開始歸併過程當中只會用到臨時數組的一小部分,可是總比每次申請釋放來的划算。



6.4 歸併排序的非遞歸實現

咱們知道遞歸算法是很消耗系統的堆棧,並且很容易形成內存的溢出。因此咱們下面咱們使用非遞歸的方法來實現歸併排序。

非遞歸算法的思想是一開始對數組兩兩進行歸併,而後對兩個元素組成的集合在進行兩兩歸併。最後完成數組的排序。下面使用圖片來講明

 

6.4.1 非遞歸歸併排序的僞代碼描述



/*

* Use loop method to implement the merge sort

* @param a A integer array need to sort

* @param n The length of the array

*/

voidmerger_SortLoop(elementType a[], int n) {

int length;

elementType *tmpA;

length = 1;

tmpA = malloc(n * sizeof(elementType));

if (tmpA != NULL) {

while (length < n) {

/*

* merge ordered sub-sequence into <code>tmpA</code>

*/

mergerPass(a, tmpA, n, length);

length *= 2;

/*

* merge ordered sub-sequence from <code>tmpA</code> into <code>a</code>

*/

mergerPass(tmpA, a, n, length);

length *= 2;

}

free(tmpA);

} else {

printf("no enough to apply for temporary array");

}

}



7 各類排序算法在PAT的測試結果

7.1測試題測試樣例

給定N個(長整型範圍內的)整數,要求輸出從小到大排序後的結果。

本題旨在測試各類不一樣的排序算法在各類數據狀況下的表現。各組測試數據特色以下:

  • 數據1:只有1個元素;

  • 數據211個不相同的整數,測試基本正確性;

  • 數據3103個隨機整數;

  • 數據4104個隨機整數;

  • 數據5105個隨機整數;

  • 數據6105個順序整數;

  • 數據7105個逆序整數;

  • 數據8105個基本有序的整數;

  • 數據9105個隨機正整數,每一個數字不超過1000

輸入格式:

輸入第一行給出正整數N(≤10​5​​),隨後一行給出N個(長整型範圍內的)整數,其間以空格分隔。

輸出格式:

在一行中輸出從小到大排序後的結果,數字間以1個空格分隔,行末不得有多餘空格。

輸入樣例:


114 981 10 -17 0 -20 29 50 8 43 -5

輸出樣例:

-20 -17 -5 0 4 8 10 29 43 50 98





7.2冒泡排序的測試結果

 

7.3插入排序測試結果

 

7.4 堆排序的測試結果

7.5希爾排序的測試結果

可是希爾排序也有經過的例子

 

7.6 歸併排序遞歸算法測試結果

7.7 歸併算法非遞歸算法的測試結果

 

 

7.8 結果分析

從上面的測試結果來看,堆排序,歸併排序都完美經過了測試,並且效率挺高的。

冒泡排序沒有經過測試很正常,由於時間複雜度爲O(N^2).

是我感到詫異的是,插入排序竟然經過了測試,雖然挺耗時,可是希爾排序在測試點7105個逆序整數居然沒有經過。個人希爾排序使用Sedgewick序列。不是理論上是O(N^(4/3)),怎麼會沒有經過呢。可是時間複雜度和冒泡排序相近的插入排序竟然經過了。好奇怪。並且插入排序在測試點7105個逆序整數所有是逆序數最壞的時間複雜度爲O(N^2),怎麼就經過了呢。好奇怪。後來屢次對希爾排序進行測試,發現有時候能夠經過,有時候沒有經過,估計是受機器的影響。感受希爾排序效率不高,平均的都在5000ms以上

 

 

8各類排序的源代碼

 

 1 /*
 2  * bubbleSort.c
 3  *
 4  *  Created on: 2017年5月18日
 5  *      Author: ygh
 6  */
 7 
 8 #include <stdio.h>
 9 
10 typedef int elementType;
11 #define  MAX_LENGTH 100000
12 
13 /*
14  * Swap two integer number value
15  */
16 void swap(elementType *a, elementType *b) {
17     int temp = *b;
18     *b = *a;
19     *a = temp;
20 }
21 /*
22  * A method to implement bubble sort.If the bubble sort has no any swap
23  * operation at one time,indicating the array has been ordered.So we use a
24  * tag to make it effective
25  *@param a A integer array need to sort
26  *@param n The length of the array
27  */
28 void bubble_sort(elementType a[], int n) {
29     int i, j, flag;
30     for (i = n - 1; i >= 0; i--) {
31         flag = 0;
32         for (j = 0; j < i; j++) {
33             if (a[j] > a[j + 1]) {
34                 swap(&a[j], &a[j + 1]);
35                 flag = 1;
36             }
37         }
38         if (flag == 0) {
39             break;
40         }
41     }
42 }
43 
44 /*
45  * Print the array to console
46  * @param a A integer array need to sort
47  * @param n The length of the array
48  */
49 void printArray(int a[], int n) {
50     int i;
51     for (i = 0; i < n; i++) {
52         if (i == n - 1) {
53             printf("%d", a[i]);
54         } else {
55             printf("%d ", a[i]);
56         }
57     }
58     printf("\n");
59 }
60 
61 /*
62  * Get input data from command
63  */
64 void getInputData(elementType *a, int n) {
65     int i;
66     elementType x;
67     for (i = 0; i < n; i++) {
68         scanf("%d", &x);
69         a[i] = x;
70     }
71 }
72 
73 int main() {
74     int a[MAX_LENGTH];
75     int n;
76     scanf("%d", &n);
77     getInputData(a, n);
78     bubble_sort(a, n);
79     printArray(a, n);
80     return 0;
81 }
Bubble_Sort

 

 

 1 /*
 2  * insertionSort.c
 3  *
 4  *  Created on: 2017年5月18日
 5  *      Author: ygh
 6  */
 7 
 8 #include <stdio.h>
 9 
10 #define  MAX_LENGTH 100000
11 typedef int elementType;
12 
13 /*
14  * Swap two integer number value
15  */
16 void swap(elementType *a, elementType *b) {
17     int temp = *b;
18     *b = *a;
19     *a = temp;
20 }
21 /*
22  * Implement insertion sort.
23  *@param a A integer array need to sort
24  *@param n The length of the array
25  */
26 void insertion_sort(elementType a[], int n) {
27     int i, j;
28     elementType temp;
29     for (i = 1; i < n; i++) {
30         temp = a[i];
31         for (j = i; j > 0 && a[j - 1] > temp; j--) {
32             a[j] = a[j - 1];
33         }
34         a[j] = temp;
35     }
36 
37 }
38 
39 /*
40  * Print the array to console
41  * @param a A integer array need to sort
42  * @param n The length of the array
43  */
44 void printArray(int a[], int n) {
45     int i;
46     for (i = 0; i < n; i++) {
47         if (i == n - 1) {
48             printf("%d", a[i]);
49         } else {
50             printf("%d ", a[i]);
51         }
52     }
53     printf("\n");
54 }
55 
56 /*
57  * Get input data from command
58  */
59 void getInputData(elementType *a, int n) {
60     int i;
61     elementType x;
62     for (i = 0; i < n; i++) {
63         scanf("%d", &x);
64         a[i] = x;
65     }
66 }
67 
68 int main() {
69     int a[MAX_LENGTH];
70     int n;
71     scanf("%d", &n);
72     getInputData(a, n);
73     insertion_sort(a, n);
74     printArray(a, n);
75     return 0;
76 }
Insertion_Sort

 

  1 /*
  2  * shellSort.c
  3  *
  4  *  Created on: 2017年5月18日
  5  *      Author: ygh
  6  */
  7 
  8 #include <stdio.h>
  9 #include <math.h>
 10 
 11 #define  MAX_LENGTH 100000
 12 typedef int elementType;
 13 
 14 /*
 15  * Swap two integer number value
 16  */
 17 void swap(elementType *a, elementType *b) {
 18     int temp = *b;
 19     *b = *a;
 20     *a = temp;
 21 }
 22 
 23 int getSedgewickStep(int *step, int n) {
 24     int i, v1, v2, counter = 0;
 25     i = 0;
 26     for (i = 0; i < n; i++) {
 27         v1 = 9 * pow(4, i) - 9 * pow(2, i) + 1;
 28         if (v1 > 0 && v1 < n) {
 29             step[counter++] = v1;
 30         }
 31         v2 = pow(4, i) - 3 * pow(2, i) + 1;
 32         if (v2 > 0 && v2 < n) {
 33             step[counter++] = v2;
 34         }
 35         if (v1 > n && v2 > n) {
 36             break;
 37         }
 38     }
 39     return counter;
 40 }
 41 
 42 /*
 43  * A method to implement bubble sort.If the bubble sort has no any swap
 44  * operation at one time,indicating the array has been ordered.So we use a
 45  * tag to make it effective
 46  *@param a A integer array need to sort
 47  *@param n The length of the array
 48  */
 49 void bubble_sort(int a[], int n) {
 50     int i, j, flag;
 51     for (i = n - 1; i >= 0; i--) {
 52         flag = 0;
 53         for (j = 0; j < i; j++) {
 54             if (a[j] > a[j + 1]) {
 55                 swap(&a[j], &a[j + 1]);
 56                 flag = 1;
 57             }
 58         }
 59         if (flag == 0) {
 60             break;
 61         }
 62     }
 63 }
 64 
 65 /*
 66  * Implement base shell sort
 67  *@param a A integer array need to sort
 68  *@param n The length of the array
 69  */
 70 void shell_sort_expand_Sedgewick(elementType a[], int n) {
 71     int i, j, d, counter, step;
 72     elementType temp;
 73     int sequence[] = { 1, 5, 19, 41, 109, 209, 505, 929, 2161, 3905, 8929,
 74             16001, 6289, 64769 };
 75     counter = 13;
 76     /*int sequence[n / 2];
 77      counter = getSedgewickStep(sequence, n);
 78      bubble_sort(sequence, counter);*/
 79     /*printArray(sequence, counter);
 80      return;*/
 81     for (d = 0; d < counter && sequence[d] < n; d++) {
 82         step = sequence[d];
 83         for (i = step; i < n; i++) {
 84             temp = a[i];
 85             for (j = i; j >= step && a[j - step] > temp; j -= step) {
 86                 a[j] = a[j - step];
 87             }
 88             a[j] = temp;
 89         }
 90     }
 91 
 92 }
 93 
 94 /*
 95  * Implement base shell sort
 96  *@param a A integer array need to sort
 97  *@param n The length of the array
 98  */
 99 void shell_sort_expand_Sedgewick2(elementType a[], int n) {
100     int i, j, d, counter, step;
101     elementType temp;
102     int sequence[n / 2];
103     counter = getSedgewickStep(sequence, n);
104     bubble_sort(sequence, counter);
105     for (d = 0; d < counter && sequence[d] < n; d++) {
106         step = sequence[d];
107         for (i = step; i < n; i++) {
108             temp = a[i];
109             for (j = i; j >= step && a[j - step] > temp; j -= step) {
110                 a[j] = a[j - step];
111             }
112             a[j] = temp;
113         }
114     }
115 
116 }
117 
118 /*
119  * Implement base shell sort
120  *@param a A integer array need to sort
121  *@param n The length of the array
122  */
123 void shell_sort_base(elementType a[], int n) {
124     int i, j, d;
125     elementType temp;
126     for (d = n / 2; d > 0; d = d / 2) {
127         for (i = d; i < n; i++) {
128             temp = a[i];
129             for (j = i; j >= d && a[j - d] > temp; j -= d) {
130                 a[j] = a[j - d];
131             }
132             a[j] = temp;
133         }
134     }
135 
136 }
137 
138 /*
139  * Print the array to console
140  * @param a A integer array need to sort
141  * @param n The length of the array
142  */
143 void printArray(int a[], int n) {
144     int i;
145     for (i = 0; i < n; i++) {
146         if (i == n - 1) {
147             printf("%d", a[i]);
148         } else {
149             printf("%d ", a[i]);
150         }
151     }
152     printf("\n");
153 }
154 
155 /*
156  * Get input data from command
157  */
158 void getInputData(elementType *a, int n) {
159     int i;
160     elementType x;
161     for (i = 0; i < n; i++) {
162         scanf("%d", &x);
163         a[i] = x;
164     }
165 }
166 
167 int main() {
168     int a[MAX_LENGTH];
169     int n;
170     scanf("%d", &n);
171     getInputData(a, n);
172     shell_sort_expand_Sedgewick2(a, n);
173     printArray(a, n);
174     return 0;
175 }
Shell_Sort

 

  1 /*
  2  * heapSort.c
  3  *
  4  *  Created on: 2017年5月18日
  5  *      Author: ygh
  6  */
  7 
  8 #include <stdio.h>
  9 
 10 #define  MAX_LENGTH 100000
 11 typedef int elementType;
 12 
 13 /*
 14  * Swap two integer number value
 15  */
 16 void swap(elementType *a, elementType *b) {
 17     int temp = *b;
 18     *b = *a;
 19     *a = temp;
 20 }
 21 
 22 /*
 23  * Update the element of tree make the tree to be a maximal heap
 24  * @param a A <code>elementType</code> array to store the elements
 25  * @param p The index of the element need to update
 26  * @param n The length of the array
 27  */
 28 void percDowm(elementType a[], int p, int n) {
 29     int parent, child;
 30     elementType x;
 31     x = a[p];
 32     for (parent = p; (parent * 2 + 1) < n; parent = child) {
 33         child = parent * 2 + 1;
 34         if ((child != n - 1) && a[child] < a[child + 1]) {
 35             child++;
 36         }
 37         if (x >= a[child]) {
 38             break;
 39         } else {
 40             a[parent] = a[child];
 41         }
 42     }
 43     a[parent] = x;
 44 }
 45 
 46 /*
 47  * Implement heap sort
 48  * @param a A integer array need to sort
 49  * @param n The length of the array
 50  */
 51 void heap_sort(elementType a[], int n) {
 52     int i;
 53     /*
 54      * Build max heap
 55      */
 56     for (i = n / 2 - 1; i >= 0; i--) {
 57         percDowm(a, i, n);
 58     }
 59 
 60     /*
 61      * Swap and update heap
 62      */
 63     for (i = n - 1; i > 0; i--) {
 64         swap(&a[0], &a[i]);
 65         percDowm(a, 0, i);
 66     }
 67 }
 68 
 69 /*
 70  * Print the array to console
 71  * @param a A integer array need to sort
 72  * @param n The length of the array
 73  */
 74 void printArray(int a[], int n) {
 75     int i;
 76     for (i = 0; i < n; i++) {
 77         if (i == n - 1) {
 78             printf("%d", a[i]);
 79         } else {
 80             printf("%d ", a[i]);
 81         }
 82     }
 83     printf("\n");
 84 }
 85 
 86 /*
 87  * Get input data from command
 88  */
 89 void getInputData(elementType *a, int n) {
 90     int i;
 91     elementType x;
 92     for (i = 0; i < n; i++) {
 93         scanf("%d", &x);
 94         a[i] = x;
 95     }
 96 }
 97 
 98 int main() {
 99     int a[MAX_LENGTH];
100     int n;
101     scanf("%d", &n);
102     getInputData(a, n);
103     heap_sort(a, n);
104     printArray(a, n);
105     return 0;
106 }
Heap_Sort

 

  1 /*
  2  * mergeSort.c
  3  *
  4  *  Created on: 2017年5月18日
  5  *      Author: ygh
  6  */
  7 
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 #define  MAX_LENGTH 100000
 11 
 12 typedef int elementType;
 13 
 14 /*
 15  * Swap two integer number value
 16  */
 17 void swap(elementType *a, elementType *b) {
 18     int temp = *b;
 19     *b = *a;
 20     *a = temp;
 21 }
 22 
 23 /*
 24  * Merge sub-sequence to original array.
 25  * @param a original <code>elementType</code> array to store the elements
 26  * @param tmpA temporary  <code>elementType</code> array to store the temporary elements
 27  * @param l The start index of left sub-sequence
 28  * @param r The start index of left sub-sequence
 29  * @param rightEnd The end index of left sub-sequence
 30  */
 31 void merge(elementType a[], elementType tmpA[], int l, int r, int rightEnd) {
 32     /*
 33      * lefeEnd is the r-1,the sub-sequence is adjacent
 34      */
 35     int leftEnd = r - 1;
 36     /*
 37      * tmp is the counter of the <code>tmpA</code>
 38      * we should let <code>tmpA</code> index corresponding original array
 39      */
 40     int tmp = l;
 41     /*
 42      * Record the quantity of the all elements
 43      */
 44     int numElements = rightEnd - l + 1;
 45     int i;
 46     while (l <= leftEnd && r <= rightEnd) {
 47         if (a[l] <= a[r]) {
 48             tmpA[tmp++] = a[l++];
 49         } else {
 50             tmpA[tmp++] = a[r++];
 51         }
 52     }
 53     while (l <= leftEnd) {
 54         tmpA[tmp++] = a[l++];
 55     }
 56     while (r <= rightEnd) {
 57         tmpA[tmp++] = a[r++];
 58     }
 59 
 60     /*
 61      * Put <code>tmpA</code> elements into the original array
 62      */
 63     for (i = 0; i < numElements; i++, rightEnd--) {
 64         a[rightEnd] = tmpA[rightEnd];
 65     }
 66 }
 67 
 68 /*
 69  * Implement the merge sort
 70  * @param a original <code>elementType</code> array to store the elements
 71  * @param tmpA temporary  <code>elementType</code> array to store the temporary elements
 72  * @param l The start index of the array which need to sort
 73  * @param rightEnd The end index of the array which need to sort
 74  */
 75 void mergetSortRecursive(elementType a[], elementType tmpA[], int l,
 76         int rightEnd) {
 77     int center;
 78     if (l < rightEnd) {
 79         center = (l + rightEnd) / 2;
 80         mergetSortRecursive(a, tmpA, l, center);
 81         mergetSortRecursive(a, tmpA, center + 1, rightEnd);
 82         merge(a, tmpA, l, center + 1, rightEnd);
 83     }
 84 }
 85 
 86 /*
 87  * Implement merge sort
 88  * @param a A integer array need to sort
 89  * @param n The length of the array
 90  */
 91 void merger_sortRecursive(elementType a[], int n) {
 92     elementType *tmpA;
 93     tmpA = malloc(n * sizeof(elementType));
 94     if (tmpA != NULL) {
 95         mergetSortRecursive(a, tmpA, 0, n - 1);
 96         free(tmpA);
 97     } else {
 98         printf("no enough space to apply for temporary array");
 99     }
100 }
101 
102 /*
103  *merge ordered sub-sequence
104  * @param a original <code>elementType</code> array to store the elements
105  * @param tmpA temporary  <code>elementType</code> array to store the temporary elements
106  * @param n The length of the a
107  * @param the ordered current sub-sequence length
108  */
109 void mergerPass(elementType a[], elementType tmpA[], int n, int lenth) {
110     int i, j;
111     /*
112      * The loop will stop when meet the last two ordered sub-sequence
113      * The rest may be two sub-sequence of one sub-sequence
114      */
115     for (i = 0; i <= n - 2 * lenth; i += lenth * 2) {
116         merge(a, tmpA, i, i + lenth, i + 2 * lenth - 1);
117     }
118     /*
119      *If the rest of is two sub-sequence
120      */
121     if (i + lenth < n) {
122         merge(a, tmpA, i, i + lenth, n - 1);
123     } else {
124         for (j = i; j < n; j++)
125             tmpA[j] = a[j];
126     }
127 }
128 
129 /*
130  * Use loop method to implement the merge sort
131  * @param a A integer array need to sort
132  * @param n The length of the array
133  */
134 void merger_SortLoop(elementType a[], int n) {
135     int length;
136     elementType *tmpA;
137     length = 1;
138     tmpA = malloc(n * sizeof(elementType));
139     if (tmpA != NULL) {
140         while (length < n) {
141             /*
142              * merge ordered sub-sequence into <code>tmpA</code>
143              */
144             mergerPass(a, tmpA, n, length);
145             length *= 2;
146             /*
147              * merge ordered sub-sequence from <code>tmpA</code> into <code>a</code>
148              */
149             mergerPass(tmpA, a, n, length);
150             length *= 2;
151         }
152         free(tmpA);
153     } else {
154         printf("no enough to apply for temporary array");
155     }
156 }
157 
158 /*
159  * Print the array to console
160  * @param a A integer array need to sort
161  * @param n The length of the array
162  */
163 void printArray(int a[], int n) {
164     int i;
165     for (i = 0; i < n; i++) {
166         if (i == n - 1) {
167             printf("%d", a[i]);
168         } else {
169             printf("%d ", a[i]);
170         }
171     }
172     printf("\n");
173 }
174 
175 /*
176  * Get input data from command
177  */
178 void getInputData(elementType *a, int n) {
179     int i;
180     elementType x;
181     for (i = 0; i < n; i++) {
182         scanf("%d", &x);
183         a[i] = x;
184     }
185 }
186 
187 int main() {
188     int a[MAX_LENGTH];
189     int n;
190     scanf("%d", &n);
191     getInputData(a, n);
192 //    merger_sortRecursive(a, n);
193     merger_SortLoop(a, n);
194     printArray(a, n);
195     return 0;
196 }
Merge_Sort

 

辛苦一天,數據結構課程的編程練習總算是進入了前100名。付出是值得的

相關文章
相關標籤/搜索