插入排序
基本思想:每次將一個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子序列中,直到插入完成。
----直接插入排序
在有序子列裏找到第i個的位置k,將L[k.....i-1]中元素向後移動一個位置
void InsertSort(ElemType A[],int n){
int i,j;
for(i=2;i<=n;i++){
if(A[i].key<A[i-1].key){
A[0]=A[i];
for(j=i-1;A[0].key<A[j].key;--j){
A[j+1]=A[j];
}
A[j+1]=A[0];
}
}
}
空間複雜度O(1);時間複雜度O(n^2);適合於順序存儲和鏈式存儲的線性表。
------折半插入排序
先折半查找出元素的待插入位置,再統一移動插入
順序存儲的線性表的有序子表可以用折半查找來實現;比較次數與元素個數有關,時間複雜度O(n^2)
------希爾排序
將待排序表分成若干個子表,分別進行直接插入排序,再對全表進行一次直接插入排序。
void ShellSort(ElemType A[],int n){
for(dk=n/2;dk>=1;dk=dk/2)
for(i=dk+1;i<=n;++i){
if(A[i].key<A[i-dk].key){
A[0]=A[i];
for(j=i-dk;j>0&&A[0]<A[j];k-=dk){
A[j+dk]=A[j];
}
A[j+dk]=A[0];
}
}
}
時間複雜度O(n^2),不穩定;適用於順序存儲
交換排序
-----冒泡排序
基本思想:待排序表長n,從後往前兩兩比較相鄰元素的值,若爲逆序,交換。
void BubbleSort(ElemType A[],int n){
for(i=0;i<n-1;i++){
flag=false;
for(j=n-1;j>i;j--){
if(A[j-1].A[j]){
swap(A[j-1],A[j]);
flag=true;
}
}
if(flag==false)
return;
}
}
時間複雜:最好O(n),最壞O(n^2)
------快速排序
基本思想:基於分治法,任取一個元素作爲基準pivot,通過一趟排序劃分兩邊部分,一邊小於pivot,一遍大於等於pivot。pivot放在最終位置,然後分別遞歸的對倆子表重複上述排序。
int partion(int data[],int low,int high)
{
int t=data[low];
while(low<high)
{
while(low<high&&data[high]>=t)
{
high--;
}
data[low]=data[high];
while(low<high&&data[low]<=t)
{
low++;
}
data[high]=data[low];
}
data[low]=t;
return low;
}
void quicksort(int data[],int low,int high)
{
int part;
if(low<high)
{
part=partion(data,low,high);
// printf("%d\n",part);
quicksort(data,low,part-1);
quicksort(data,part+1,high);
}
}
---------------------
作者:xulu_258
來源:CSDN
原文:https://blog.csdn.net/xulu_258/article/details/51319047
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!
空間複雜度:最壞情況O(n^2)
不穩定算法
選擇排序
基本思想:每一趟i在後面n-i+1個待排序元素中選取關鍵字最小的元素,作爲有序子序的第i個元素,直到第n-1趟完成。
------簡單選擇排序
時間效率:n(n-1)/2次,O(n^2);不穩定
比較次數與初始狀態無關
------堆排序
樹形選擇排序,特點:將L[n] 看成是一顆完全二叉樹的順序存儲結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關係,在當前無序區選擇最大(小)關鍵字;
小根堆:L(i)<=L(2i) 且L(i)<=L(2i+1)
大根堆:L(i)>=L(2i+1) (1<=i<=n/2);最大元素存放在根結點中
建堆時間:O(n) 時間複雜度:O(nlog2 n) 不穩定
歸併排序和基數排序
--------歸併排序
基本思想:歸併的含義將兩個或兩個以上的有序表組合成一個新的有序表;調用n/2h次算法 ;整個歸併需進行log2 n趟
空間複雜度:O(n) 時間複雜度O(nlog2 n);穩定排序;排序次數與初始狀態無關
--------基數排序
基本思想:基於關鍵字各位的大小進行排序
性能:空間O(r) r個隊列; 時間O(d(n+r)) 與初始狀態無關;穩定
內部排序算法得比較及應用
------時空複雜度
平均情況下時間複雜度O(n^2):簡單選擇排序,直接插入排序,冒泡排序
空間複雜度:簡單選擇排序,插入排序冒泡排序,希爾排序,堆排序藉助常數個輔助空間
快速排序使用小的輔助棧O(log2 n);二路歸併O(n)
穩定:插入排序,冒泡排序,歸併排序,基數排序
小結:
- 若n較小,可以採用直接插入或簡單選擇排序;直接插入排序的移動操作較多,記錄信息本身量大時,用簡單排序
- 若文件的初始狀態已按關鍵字基本有序,選擇直接插入或冒泡排序
- 若n較大,採用時間複雜度O(nlog2 n)快速排序,堆排序,遞歸排序;快速排序被認爲目前內部排序中最好的方法;堆排序所需的輔助空間少於快速排序,這倆是不穩定排序;
- 若n很大,並記錄的關鍵字位數較少且可分解採用基數排序
- 記錄本身信息量較大,避免耗費大量時間移動記錄,可用鏈表作爲存儲結構
外部排序
歸併排序
歸併趟數S=logm r(向上取整)
歸併路數m個元素中關鍵字最小比較m-1次,每趟歸併n個元素需要(n-1)*(m-1)
S趟歸併比較總數:S(n-1)*(m-1)
----置換-選擇算法
初始待排文件F1,初始歸併段文件FO,內存工作區爲WA,內存工作區可容納W個記錄;
步驟:
- 從待排文件F1輸入W個記錄到工作區WA
- 從內存工作區WA中選出關鍵字最小的記錄MIN
- 將MIN記錄輸出到FO中
- 若F1未讀完,則從F1輸入下一個記錄到WA
- 從WA中所有關鍵字比MIN大的記錄中選出最小的,作爲新的MIN
- 重複3-5