1、插入排序算法
1.直接插入排序數組
2.折半插入排序數據結構
3.希爾排序spa
2、交換類排序.net
1.冒泡排序3d
2.快速排序blog
3、選擇類排序排序
1.簡單選擇排序 索引
2.堆排序內存
4、歸併排序
二路歸併排序
歸併排序
public static void insertionSort(int[] a) {
int tmp;
for (int i = 1; i < a.length; i++) {
for (int j = i; j > 0; j--) {
if (a[j] < a[j - 1]) {
tmp = a[j - 1];
a[j - 1] = a[j];
a[j] = tmp;
}
}
}
}
尋找插入的位置採用折半查找法
希爾(Shell)排序又稱爲縮小增量排序,它是一種插入排序。它是直接插入排序算法的一種威力增強版。
把記錄按步長 gap 分組,對每組記錄採用直接插入排序方法進行排序。隨着步長逐漸減少,所分紅的組包含的記錄愈來愈多,當步長的值減少到 1 時,整個數據合成爲一組,構成一組有序記錄,則完成排序。gap1 = N / 2 ,gapk = gap(k-1) / 2
public static void bubbleSort(int[] a) {
int flag;
int temp;
for (int i = a.length-1; i > 0; --i) {
flag = 0;
for (int j = 1; j <= i; ++j) {
if (a[j] < a[j - 1]) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
flag = 1;
}
}
if(flag == 0)
return;
}
}
public static void partition(int []array,int lo,int hi){
//固定的切分方式
int key=array[lo];
while(lo<hi){
while(array[hi]>=key&&hi>lo){
hi--;
}
array[lo]=array[hi];
while(array[lo]<=key&&hi>lo){
lo++;
}
array[hi]=array[lo];
}
array[hi]=key;
partition(int []array,lo, hi-1);
partition(int []array, lo, hi+1);
}
public void selectionSort(int[] list) {
// 須要遍歷得到最小值的次數
// 要注意一點,當要排序 N 個數,已經通過 N-1 次遍歷後,已是有序數列
for (int i = 0; i < list.length - 1; i++) {
int temp = 0;
int index = i; // 用來保存最小值得索引
// 尋找第i個小的數值
for (int j = i + 1; j < list.length; j++) {
if (list[index] > list[j]) {
index = j;
}
temp = list[index];
list[index] = list[i];
list[i] = temp;
printAll(list);
}
}
① 先將初始文件R[1..n]建成一個大根堆,此堆爲初始的無序區
② 再將關鍵字最大的記錄R[1](即堆頂)和無序區的最後一個記錄R[n]交換,由此獲得新的無序區R[1..n-1]和有序區R[n],且知足R[1..n-1].keys≤R[n].key
③因爲交換後新的根R[1]可能違反堆性質,故應將當前無序區R[1..n-1]調整爲堆。而後再次將R[1..n-1]中關鍵字最大的記錄R[1]和該區間的最後一個記錄R[n-1]交換,由此獲得新的無序區R[1..n-2]和有序區R[n-1..n],且仍知足關係R[1..n-2].keys≤R[n-1..n].keys,一樣要將R[1..n-2]調整爲堆。
……
直到無序區只有一個元素爲止。
public class HeapSort {
/**
* 構建大頂堆 數組下標從1開始
*/
public static void adjustHeap(int[] a, int i, int len) {
int temp, j;
temp = a[i];
for (j = 2 * i; j <= len; j *= 2) {// 沿關鍵字較大的孩子結點向下篩選
if (j < len && a[j] < a[j + 1])
++j; // j爲關鍵字中較大記錄的下標
if (temp >= a[j])
break;
a[i] = a[j];
i = j;
}
a[i] = temp;
}
public static void heapSort(int[] a) {
int i;
for (i = a.length / 2; i > 0; i--) {// 構建一個大頂堆
adjustHeap(a, i, a.length);
}
for (i = a.length; i > 1; i--) {// 將堆頂記錄和當前未經排序子序列的最後一個記錄交換
int temp = a[1];
a[1] = a[i];
a[i] = temp;
adjustHeap(a, 1, i - 1);// 將a中前i-1個記錄從新調整爲大頂堆
}
}
public static void main(String[] args) {
int a[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
heapSort(a);
System.out.println(Arrays.toString(a));
}
}
外部排序指的是大文件的排序,即待排序的記錄存儲在外存儲器上,待排序的文件沒法一次裝入內存,須要在內存和外部存儲器之間進行屢次數據交換,以達到排序整個文件的目的。外部排序最經常使用的算法是多路歸併排序,即將原文件分解成多個可以一次性裝入內存的部分,分別把每一部分調入內存完成排序。而後,對已經排序的子文件進行歸併排序。
過程 :
1.初始歸併段生成
將文件分段輸入內存並排序,排序完的文件稱歸併段,將其寫入外存,這樣就造成了許多初始歸併段。
置換-選擇排序
文件輸入記錄,當填滿緩衝區後,選擇最小記錄輸出,空缺位置由下個輸入記錄取代,輸出記錄即爲初始歸併段的一部分。(新填充的記錄若是不能成爲當前歸併段的一部分,也就是說比當前歸併段最大記錄小,那麼等待下一個歸併段提供選擇)
2.最佳歸併樹創建
二路歸併即用哈夫曼樹,I/O次數 = 帶權路徑長度*2。
平均狀況
快速排序、希爾排序、堆排序、歸併排序 O(log2n)
其餘的爲O(n平方)
最壞狀況
快排爲O(n平方),越無序越好
其餘和平均狀況同樣
最好狀況
有序的狀況下,直接插入排序和冒泡排序爲O(n)
快排爲O(log2n)
歸併排序爲O(n)
快速排序、希爾排序、簡單選擇排序、堆排序爲不穩定的
其他爲穩定的