經典的各類排序總結

2021-06-09 13:52:28 字數 2899 閱讀 8730

1. 插入排序

實現原始碼:

void insertsort(int* arr, unsigned int len)

unsigned int i;

unsigned int j;

for (i = 1; i < len; i++)

arr[j + 1] = x;

}}

效能分析:假設需要從小到大進行排序,則插入排序的最壞情形是原來的陣列是按照從大到小的順序排列的,這樣需要的時間複雜度是:

插入排序的最好情形是原來的陣列已經從小到大排好序了,則時間複雜度是:

接下來是插入排序的平均情況,其時間複雜度為:

最後,插入排序是穩定的。                         

2. 折半插入排序

在前面插入排序中,由於每次在插入的過程中,都需要與前面已排好序的元素進行比較,但是需要都進行比較嗎?考慮到已經排好序這個特點,所以在比較的時候可以採用折半的方式,這裡給出折半插入排序的實現原始碼:

void inserthalfsort(int* arr, unsigned int len)

unsigned int i,j,low,mid,high,upper;

for (i = 1; i < len; i++)

else if (x < arr[mid])

else

mid = (low + high) / 2;

} if (arr[mid] <= x)

else

for (j = i; j >= upper + 1; j--)

arr[j] = x;

}}

該排序演算法的平均時間複雜度為o(nlgn),最好情形依舊為o(n),且是穩定的。

3. 希爾排序

希爾排序是對插入排序的又一次成功的改良,適用於大量資料的排序,且**簡潔:

void shellsort(int* arr, int len)

arr[j + k] = x;

} k = k / 2;

}}

4. 歸併排序歸併排序的關鍵是將兩個已經排好序的陣列合併成乙個排序陣列,以下是合併函式的實現原始碼:

//將兩個有序的陣列合併到一起

void merge(int* arr, unsigned int begin, unsigned int mid, unsigned int high)

unsigned int i = 0;

unsigned int j = 0;

unsigned int k = 0;

while (i < len1 && j < len2)

else

k++;

} if (i == len1) }

if (j == len2) }

//將臨時陣列中的元素賦給原陣列

for (i = 0; i < len1 + len2; i++)

//釋放空間

free(temparr);

}

接下來只要進行遞迴歸併排序即可:

//歸併排序

void mergesort(int* arr, unsigned int low, unsigned int high)

}

歸併排序的時間複雜度為o(nlgn),且是穩定的。

5. 快速排序

快速排序和歸併排序一樣,採用了分治的思想。快速排序是每次選擇乙個主元,然後將小於或等於主元的元素放到主元的左邊,其餘的放到主元的右邊。以下是實現原始碼:

//交換兩個整數

void swap(int* x, int* y)

int split(int* arr, int low, int high)

j++;

} swap(&arr[i], &arr[low]);

return i;

}//快速排序

void quicksort(int* arr, int low, int high)

int w = split(arr, low, high);

quicksort(arr, low, w - 1);

quicksort(arr, w + 1, high);

}

快速排序的最壞情況是出現單邊樹的情況,此時快速排序的時間複雜度為o(n^2),其餘情況下時間複雜度都是o(nlgn)。

6. 計數排序

如果已知序列中比元素x小的個數,則可以確定元素x在排序後的位置。這就是計數排序的基本思想,計數排序需要兩個輔助陣列b和c,b表示排好序的輸出陣列,c用於儲存每個元素在原序列中比該元素小的個數,則有以下實現原始碼:

void countsort(int* a, int* b, int* c, int len, int k)

//計數陣列取值為a[i]的元素個數

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

//計數陣列取值為小於或等於i的元素個數,放在c[i]裡面

for (i = 1; i < len; i++)

for (i = len - 1; i >= 0; i--)

}

計數排序的有點是線性時間和穩定性,但是由於計數排序的執行時間與輸入引數的取值規模有關,所以在有些情況下會達到平方級時間,所以具有一定的侷限性。

7. 基數排序

8. 桶排序

9. 堆排序

經典排序總結

氣泡排序 穩定 依次比較兩個相鄰的元素,把大的換到後面,一次迴圈完成後的結果是,最大的數字排在最後。重複以上步驟 除了最後乙個 直到排完。void bubble sort vector int nums 選擇排序 void select sort vector int nums swap nums ...

經典排序演算法總結

排序演算法是離散數學和資料結構學科最基本的演算法,雖然知道這些排序演算法的名字,但是一直沒有研究過它們的實現原理。現在把它們收集起來,並一一親自實現,來加深對排序演算法的理解。1,氣泡排序 最簡單的排序演算法,從第乙個元素開始比較相鄰元素大小,如果前邊元素大於後邊元素則交換位置,否則將下標移到下乙個...

經典排序演算法總結

插入排序 選擇排序 歸併排序 排序方法 平均情況 最好最差 空間複雜度 穩定性氣泡排序o n2 o n 2 o n o n o n2 o n 2 o 1 o 1 穩定快速排序o nlogn o nlog n o nlogn o nlog n o n2 o n 2 o nlogn o nlog n 不...