一般使用的八大排序演算法是:插入排序、選擇排序、氣泡排序、希爾排序、歸併排序、快速排序、堆排序、基數排序,每個方法有其適合的使用場景,可以根據具體資料進行選擇.
幾個概念:
內部排序:排序期間元素全部存放在記憶體中的排序;
外部排序:排序期間元素無法全部存放在記憶體中,必須在排序過程中根據要求不斷地進行內外存之間移動地排序;
(這八種排序演算法中除了多路歸併排序是外部排序,其他都是內部排序)
穩定性:指的是經過排序後,值相同的元素保持原來順序中的相對位置不變.
各演算法時間複雜度、空間複雜度、所需輔助空間與穩定性如下:
1.氣泡排序:
氣泡排序思想很簡單,就是對每個下標i,取j從0到n-1-i(n是陣列長度)進行遍歷,如果兩個相鄰的元素s[j]>s[j+1],就交換,這樣每次最大的元素已經移動到了後面正確的位置.
void
bubblesort
(vector<
int>
&s)}
}
2.插入排序:
插入排序又分為簡單插入排序和折半插入排序;簡單插入排序思想是每趟排序把元素插入到已排好序的陣列中,折半插入排序是改進的插入排序,由於前半部分為已排好序的數列,這樣我們不用按順序依次尋找插入點,可以採用折半查詢的方法來加快尋找插入點的速度.
簡單插入排序:
void
insertsort
(vector<
int>
&s)}
}}
折半插入排序:void
binaryinsertsort
(vector<
int>
&s)//統一移動元素,將該元素插入到正確的位置
temp = s[i]
;for
(j = i; j > high +
1; j--
) s[high +1]
= temp;
}}
插入排序的特點:
1.穩定;
2.最壞情況下比較n*(n-1)/2次,最好情況下比較n-1次;
3.第k次排序後,前k個元素已經是從小到大排好序的
3.簡單選擇排序:
選擇排序思想是對每個下標i,從i後面的元素中選擇最小的那個和s[i]交換.
void
selectsort
(vector<
int>
&s)swap
(s[i]
, s[min]);}}}
選擇排序的特點:
1.不穩定;
2.每趟排序後前面的元素肯定是已經排好序的了,每次排序後可以確定乙個元素會在其最終位置上.
4.快速排序:
快速排序是內排序中平均效能較好的排序,思想是每趟排序時選取乙個資料(通常用陣列的第乙個數)作為關鍵資料,然後將所有比它小的數都放到它的左邊,所有比它大的數都放到它的右邊.
void
quicksort
(vector<
int>
&s,int low,
int high)
s[l]
= val;
quicksort
(s, low, l -1)
;quicksort
(s, r +
1, high)
;}
快速排序的特點:
1.不穩定;
2.快速排序過程中不會產生有序子串行,但每一趟排序後都有乙個元素放在其最終位置上;
3.每次選擇的關鍵值可以把陣列分為兩個子陣列的時候,快速排序演算法的速度最快,當陣列已經是正序或逆序時速度最慢;
4.遞迴次數與每次劃分後得到的分割槽的處理順序無關;
5.對n個關鍵字進行快速排序,最大遞迴深度為n,最小遞迴深度為log2n;
上面的快速排序演算法是遞迴演算法,非遞迴演算法使用棧來實現:
//進行區域的劃分
intpartition
(vector<
int>
&s,int low,
int height)
s[low]
= val;
return low;
}//排序
void
quicksortnonrecursive
(vector<
int>
&s,int low,
int height)
if(mid +
1< height)
while
(!p.
empty()
)if(pqmid +
1< qheight)}}
}
5.希爾排序:
希爾排序是基於插入排序的一種排序演算法,思想是對長度為n的陣列s,每趟排序基於間隔h分成幾組,對每組資料使用插入排序方法進行排序,然後減小h的值,這樣剛開始時候雖然分組比較多,但每組資料很少,h減小後每組資料多但基本有序,而插入排序對已經基本有序的陣列排序效率較高.
void
shellsort
(vector<
int>
&s)}
h /=3;}}
希爾排序的特點:
1.不穩定;
2.每次排序後不能保證有乙個元素在最終位置上
6.歸併排序:
const
int maxn=
500000
,inf=
0x3f3f3f3f
;int l[maxn/2+
2],r[maxn/2+
2];void
merge
(vector<
int>
&a,int n,
int left,
int mid,
int right)
}void
mergesort
(vector<
int>
&a,int n,
int left,
int right)
}
歸併排序特點:
1.穩定;
2.可以用在順序儲存和鏈式儲存的結構;
3.時間複雜度在最好和最壞情況下都是o(nlogn)
7.堆排序:
堆排序是基於選擇排序的一種排序演算法,堆是乙個近似完全二叉樹的結構,且滿足子結點的鍵值或索引總是小於(或者大於)它的父節點。這裡採用最大堆方式:位於堆頂的元素總是整棵樹的最大值,每個子節點的值都比父節點小,堆要時刻保持這樣的結構,所以一旦堆裡面的資料發生變化,要對堆重新進行一次構建。
void
max_heapify
(vector<
int>
&arr,
int start,
int end)}}
void
heap_sort
(vector<
int>
&arr,
int len)
}
堆排序特點:
1.不穩定;
2.最壞,最好,平均時間複雜度均為o(nlogn)
8.基數排序:
基數排序是一種非比較型整數排序演算法,其原理是將資料按位數切割成不同的數字,然後按每個位數分別比較,在類似對百萬級的**號碼進行排序的問題上,使用基數排序效率較高
//尋找陣列中最大數的位數作為基數排序迴圈次數
intkeysize
(vector<
int>
&s,int n)
key =
(temp > key)
? temp : key;
}return key;
}//基數排序
void
radixsort
(vector<
int>
&s,int n)
;int order[10]
=;for(
int r =
1; key >
0; key--
, r *=10
)int k =0;
for(
int i =
0; i <
10; i++
) order[i]=0
;}}}
基數排序特點:
1.穩定;
2.時間複雜度為o (nlog®m),其中r為所採取的基數,m為堆數
3.在某些時候,基數排序法的效率高於其它的穩定性排序法。
八大排序演算法
1.直接插入排序 原理 將陣列分為無序區和有序區兩個區,然後不斷將無序區的第乙個元素按大小順序插入到有序區中去,最終將所有無序區元素都移動到有序區完成排序。要點 設立哨兵,作為臨時儲存和判斷陣列邊界之用。實現 void insertsort node l,int length void shell ...
八大排序演算法
一 概述 八大排序演算法包括 1 插入排序之直接插入排序 straight insertion sort 2 插入排序之希爾排序 shells sort 3 選擇排序之簡單選擇排序 selection sort 4 選擇排序之堆排序 heap sort 5 交換排序之氣泡排序 bubble sort...
八大排序演算法
排序的定義 輸入 n個數 a1,a2,a3,an 輸出 n個數的排列 a1 a2 a3 an 使得a1 a2 a3 an in place sort 不占用額外記憶體或占用常數的記憶體 插入排序 選擇排序 氣泡排序 堆排序 快速排序。out place sort 歸併排序 計數排序 基數排序 桶排序...