資料結構-各類排序演算法總結[結局],資料結構演算法
各類排序演算法總結五.分配類排序->基數排序:
基數排序是一種藉助於多關鍵碼排序的思想,是將單關鍵碼按基數分成“多關鍵碼”進行排序的方法。基數排序屬於”低位優先”排序法,通過反覆進行分配與收集操作完成排序.
對於數字型或字元型的單關鍵字,可以看成是由多個數位或多個字元構成的多關鍵字,
此時可以採用這種“分配-收集”的辦法進行排序,稱作基數排序法。其好處是不需要進行關鍵字間的比較。
例如:對下列這組關鍵字{278, 109, 063, 930, 589, 184, 505, 269, 008,083 },首先按其“個位元”取值分別為0, 1, …,9“分配”成10 組,之後按從0 至9 的順序將它們“收集”在一起;然後按其“十位元” 取值分別為0, 1, …,9“分配”成10 組,之後再按從0 至9 的順序將它們“收集”在一起;最後按其“百位元”重複一遍上述操作,便可得到這組關鍵字的有序序列。
在電腦上實現基數排序時,為減少所需輔助儲存空間,應採用鏈表作儲存結構,即鏈式基數排序,具體作法為:
(1)待排序記錄以指標相鏈,構成一個鏈表;
(2)“分配”時,按當前“關鍵字位”所取值,將記錄分配到不同的“鏈隊列”中,每個隊列中記錄的“關鍵字位”相同;
(3)“收集”時,按當前關鍵字位取值從小到大將各隊列首尾相鏈成一個鏈表;
(4)對每個關鍵字位均重複(2)和(3)兩步。
【效能分析】
(1)空間效率:鏈式基數排序空間複雜度為O(rd)。
(2)時間效率:基數排序的時間複雜度為O(d(n+rd))。
其中,分配為O(n); 收集為O(rd)(rd 為“基”), d 為“分配-收集”的趟數。
(3)穩定性:基數排序是一個穩定的排序方法。
六. 各種內部排序演算法的比較
1、時間效能
(1)按平均的時間效能來分,有三類排序方法:
時間複雜度為O(nlogn)的方法有:快速排序、堆排序和歸併排序,其中以快速排序為最好;
時間複雜度為O(n^2)的有:直接插入排序、起泡排序和簡單選擇排序,其中以直接插入為最好,特別是對那些對關鍵字近似有序的記錄序列尤為如此;
時間複雜度為O(n)的排序方法只有基數排序。
(2)當待排記錄序列按關鍵字順序有序時,直接插入排序和起泡排序能達到O(n)的時間
複雜度;而對於快速排序而言,這是最不好的情況,此時的時間效能蛻化為O(n^2),因此是應該盡量避免的情況。
(3)簡單選擇排序、堆排序和歸併排序的時間效能不隨記錄序列中關鍵字的分布而改變。
2、空間效能
(1)所有的簡單排序方法(包括:直接插入、起泡和簡單選擇)和堆排序的空間複雜度為O(1);
(2)快速排序為O(logn),為棧所需的輔助空間;
(3)歸併排序所需輔助空間最多,其空間複雜度為O(n);
(4)鏈式基數排序需附設隊列首尾指標,則空間複雜度為O(rd)
3、排序方法的穩定效能
當對多關鍵字的記錄序列進行LSD(基數排序)方法排序時,必須採用穩定的排序方法。
快速排序和堆排序是不穩定的排序方法。
多數情況下,排序是按記錄的主關鍵字進行的,此時不用考慮排序方法的穩定性.如果排序是按照記錄的次關鍵字進行的,則應充分考慮排序方法的穩定性.
4、各種排序方法的綜合比較和選擇
(1)各種排序方法的比較如表。
(2)選擇
選擇排序方法時需要考慮的因素有:待排序的記錄個數n;記錄本身的大小;關鍵字的
分布情況;對排序穩定性的要求;語言工具的條件;輔助空間的大小。
依據這些元素,可以得到以下幾點結論:
①待排序的記錄數目n 較小時,則採用插入排序和簡單選擇排序;
②若待排序記錄按關鍵字基本有序,則宜採用直接插入排序和冒泡排序;直接插入排序是最佳的排序方法,常與快速排序,歸併排序等其他排序方法綜合使用.
③當n 很大且關鍵字的位元較少時,採用鏈式基數排序較好;
④若n 較大,則應採用時間複雜度為O(nlogn)的排序方法:快速排序、堆排序或歸併排序。
資料結構中比較各種排序演算法 詳解 ,,,,,,,,,,
排序演算法包括:插入排序、交換排序、選擇排序以及合并排序。
其中插入排序包括直接插入排序和Shell排序,交換排序包括冒泡排序和分化交換排序,選擇排序包括直接選擇排序和堆排序。
這些排序演算法中,直接插入排序、冒泡排序和直接選擇排序這三種排序的演算法平均時間複雜度是O(n的平方);分化交換排序、堆排序和合并排序這三種排序的演算法平均時間複雜度是
資料結構C語言——實現各種排序演算法
剛做完的
#include <iostream>
using namespace std;
void BiInsertsort(int r[], int n) //插入排序(折半)
{
for(int i=2;i<=n;i++)
{
if (r[i]<r[i-1])
{
r[0] = r[i]; //設定哨兵
int low=1,high=i-1; //折半尋找
while (low<=high)
{
int mid=(low+high)/2;
if (r[0]<r[mid]) high=mid-1;
else low = mid+1;
}
int j;
for (j=i-1;j>high;j--) r[j+1] = r[j]; //後移
r[j+1] = r[0];
}
}
for(int k=1;k<=n;k++) cout<<r[k]<<" ";
cout<<"\n";
}
void ShellSort ( int r[], int n) //希爾排序
{
for(int d=n/2;d>=1;d=d/2) //以d為增量進行直接插入排序
{
for (int i=d+1;i<=n;i++)
{
r[0] = r[i]; //暫存被插入記錄
int j;
for( j=i-d; j>0 && r[0]<r[j]; j=j-d) r[j+d] = r[j]; //記錄後移d個位置
r[j+d] = r[0];
}
}
for(int i=1;i<=n;i++) cout<<r[i]<<" ";
cout<<"\n";
}
void BubbleSort(int r[], int n) //起泡排序
{
int temp,exchange,bound;
exchange=n; //第一趟起泡排序的範圍是r[0]到r[n-1]
while (exchange) //僅當上一趟排序有記錄交換才進行本趟排序
{
bound=exchange;
exchange=0;
for (int j=1; j<bound; j++) //一趟起泡排序
if (r[j]>r[j+1])
{
temp=r[j];
r[j]=r[j+1];
r[j+1]=temp;
exchange=j; ......餘下全文>>