資料結構 幾種常見的排序演算法

2021-07-24 22:23:36 字數 3286 閱讀 9143

下圖是我掌握的一些排序演算法,我將他們做了分類,當然,排序演算法遠不止這些。

a>演算法思想:假設第乙個數是有序的,那麼把後面的數拿出來插入到這個有序數的合適位置,假設是公升序(比第乙個數小則向後移動第乙個數,將數插入到第乙個數的前面),插入後有序區間擴大為兩個,依次向後,不斷拿出新的數插入到有序區間,再擴大這個有序區間直至區間大小等於排序陣列的大小。

b>時間複雜度:時間上,最好情況當序列已經是有序排列了,在這種情況下,需要進行的比較操作需(n-1)次即可,複雜度o(n)。最壞情況,序列與目標序列相反,那麼此時需要進行的比較共有n(n-1)/2次,時間複雜度忽略係數,結果為o(n^2)。平均來說插入排序演算法複雜度為o(n²)。

c>空間複雜度:由於插入排序沒有進行任何開闢空間或者遞迴的操作,顧其空間複雜度為o(1).

d>適用場景:由於插入排序的時間複雜度太大,所以不適合大量資料的排序,如果資料量少,倒是沒啥影響。

e>**實現:

#pragma once

#includeusing namespace std;

void insertsort(int* a, size_t n)

} pos++;

index = pos + 1; }}

void testinsertsort()

; insertsort(a, sizeof(a) / sizeof(a[0]));

printarr(a, sizeof(a) / sizeof(a[0]));

}

a>演算法思想:希爾排序可以認為是對直接插入排序的優化,我們知道,直接插入排序在基本有序時是非常快的,所以希爾排序就是在直接插入排序之前進行多趟預排序(直接插入排序每次只能將資料移動乙個位置,希爾的優化就體現在一次可跳躍移動),使得排序陣列接近有序,最後進行一趟直接插入排序。預排序的思想如下:

b>時間複雜度分析:希爾排序的時間複雜度介於o(n)至o(n^2)之間,相關資料顯示其具體複雜度為o(n^1.3)次方,這裡我沒有深究。

c>空間複雜度:與直接插入排序一樣,o(1)。

d>**實現

#pragma once 

#includeusing namespace std;

void shellsort(int*a, size_t size)

a[pos + gap] = tmp;

} }}void testshellsort()

; shellsort(a, sizeof(a) / sizeof(a[0]));

printarr(a, sizeof(a) / sizeof(a[0]));

}

注意:希爾排序增量的設定不能為乙個定值,要根據排序陣列的大小進行調整,同時保證最後一次為1,進行直接插入排序。

a>演算法思想:選擇排序可以一次選乙個最大的數,放在陣列的最後一位(假設公升序),也可以一次選擇兩個(乙個最大,乙個最小)分別放在最後和最前,演算法思想很簡單。

b>時間複雜度分析:選擇排序在最好和最壞的情況下都是o(n^2),因為,即使有序了,選擇排序依然每次要進行固定的選擇和比較。

c>空間複雜度分析:o(1)

d>**實現(一次選兩數版本)

#pragma once

#includeusing namespace std;

void selectsort(int *a,size_t n)

swap(a[left], a[min]);

if (left == max)

swap(a[right], a[max]);

left++;

right--; }}

void printarr(int* a,size_t n)

cout << endl;

}void testselectsort()

; selectsort(a, sizeof(a) / sizeof(a[0]));

printarr(a, sizeof(a) / sizeof(a[0]));

}

a>演算法思想:若公升序,建大堆,每次選擇堆頂元素即最大的數,和最後一位交換,再縮小堆的範圍(避免剛排好的最後乙個位置被調回去),對剩下的進行向下調整(此時只有根節點不對,左右子樹都滿足大堆)。反覆進行直到堆的範圍為0.則資料就有序了。

b>時間複雜度:建堆的時間複雜度近似為o(n*log n),每次選乙個數後進行調整的複雜度也近似為o(n*log n),時間複雜度忽略係數,結果就近似為o(n*log n).

c>空間複雜度:o(1)

d>**實現:

#pragma once

#includeusing namespace std;

void adjustdown(int* a, int root,int size)

}void heapsort(int*a, int size)

for (int j = 0; j < size; j++) }

void testheapsort()

; heapsort(a, sizeof(a) / sizeof(a[0]));

printarr(a, sizeof(a) / sizeof(a[0]));

}

注意:堆排序雖然效率很高,但是只適用於隨機序列,像鍊錶這些就不行了。

a>演算法思想:從下表為0的數開始,和後面的數依次比較,大的向後移,一趟排序之後,最大的就移動到了最後,再從下標為0的開始將次大的冒到倒數第二位。

b>時間複雜度:第一趟排序需要經過(n-1)次比較,第二次(n-2),。。。等差數列,最後忽略係數還是o(n^2)。

c>空間複雜度:o(1)

d>**實現:

#pragma once

#includeusing namespace std;

void bubblesort(int* a, size_t size)

} if (flag = false)

break;

}}void testbubblesort()

; bubblesort(a, sizeof(a) / sizeof(a[0]));

printarr(a, sizeof(a) / sizeof(a[0]));

}

氣泡排序的優化:若某趟排序沒有經過一次交換資料,說明陣列已經有序,則跳出迴圈。

大話資料結構 幾種排序演算法

這篇筆記主要是寫寫這些常見的排序演算法。思想 兩兩比較相鄰記錄的關鍵字,反序則交換,直到沒有反序為止。include 交換int型陣列l中下標i和j的值 void swap int l,int i,int j void bubblesort int l 分析 最好的情況比較n 1次,時間複雜度o n...

資料結構的幾種經典排序演算法

include include 排序演算法 偽版氣泡排序 void bubblesort int k,int n printf 總共進行了 d次比較,進行了 d次移動!count1,count2 氣泡排序 void bubblesortplus int k,int n printf 總共進行了 d次...

資料結構幾種常用排序演算法總結

其中,n表示資料規模,rd表示關鍵字取值個數,d表示關鍵字個數 穩定的排序方法 所有的簡單排序,歸併排序,基數排序 不穩定的排序方法 希爾排序,快速排序,堆排序 一般而言,排序過程中 比較 過程是在兩個相鄰關鍵字之間進行的排序方法是穩定的。就地排序方法 所有簡單排序,希爾排序,堆排序。所需輔助空間最...