排序演算法分為內部排序和外部排序兩大類。
內部排序:在計算機記憶體中完成的排序演算法
外部排序:不能再記憶體中文完成,必須在磁碟或者磁帶上完成的排序演算法
內部排序是研究的重點問題,通常我們講的八大排序演算法也主要是講的內部排序演算法。
排序演算法的穩定性和時間空間複雜度
本文重點介紹以下幾種排序演算法
1.理論思想
插入排序問題的思路是將為排序元素逐一插入至已經排序的序列,從第二個元素開始插入,直至整個序列都有序終止。給定序列,從第二個元素開始插入,若遇到相等的元素則將其插入值後面
2.演算法例程
#include#include#includevoid sort_insert(int unsort,int sort_len)
unsort[j]=temp;//移動完畢後,將j位置的元素置為temp}}
}int main()
; sort_insert(a,8);
printf("---------sorting-----------\n");
for (int i=0;i<8;i++)
printf("\n---------end-----------\n");
return 0;
}
3.穩定性分析
插入排序的複雜度為o(n^2)
1.理論思想
選擇排序的思想是每次從未排序的序列中,選擇最小(最大)的數放在排序數列的後面,形成從小到大的排序思路。
給定序列
第一趟找到最小數13,放到最前邊(與首位數字交換)
交換前:| 49 | 38 | 65 | 97 | 76 | 13 | 27 | 49 |
交換後:| 13 | 38 | 65 | 97 | 76 | 49 | 27 | 49 |
第二趟找到餘下數字| 38 | 65 | 97 | 76 | 49 | 27 | 49 |裡的最小數27,與當前陣列的首位數字進行交換,實際沒有交換,本來就在首位
交換前:| 13 | 38 | 65 | 97 | 76 | 49 | 27 | 49 |
交換後:| 13 | 27 | 65 | 97 | 76 | 49 | 38 | 49 |
第三趟繼續找到剩餘| 65 | 97 | 76 | 49 | 38 | 49 |數字裡的最小數38,與當前數列的首位進行交換
交換前:| 13 | 27 | 65 | 97 | 76 | 49 | 38 | 49 |
交換後:| 13 | 27 | 38 | 97 | 76 | 49 | 65 | 49 |
第四趟繼續找到剩餘| 97 | 76 | 49 | 65 | 49 |數字裡的最小數49,與當前數列的首位進行交換
交換前:| 13 | 27 | 38 | 97 | 76 | 49 | 65 | 49 |
交換後:| 13 | 27 | 38 | 49 | 76 | 97 | 65 | 49 |
第五趟從剩餘的| 76 | 97 | 65 | 49 |裡找到最小數49,與首位數字76交換位置
交換前:| 13 | 27 | 38 | 49 | 76 | 97 | 65 | 49 |
交換後:| 13 | 27 | 38 | 49 | 49 | 97 | 65 | 76 |
第六趟從剩餘的| 97 | 65 | 76 |裡找到最小數65
交換前:| 13 | 27 | 38 | 49 | 49 | 97 | 65 | 76 |
交換後:| 13 | 27 | 38 | 49 | 49 | 65 | 97 | 76 |
第七趟從剩餘的| 97 | 76 |裡找到最小數76
交換前:| 13 | 27 | 38 | 49 | 49 | 97 | 65 | 76 |
交換後:| 13 | 27 | 38 | 49 | 49 | 65 | 76 | 97 |
排序完畢輸出正確結果| 13 | 27 | 38 | 49 | 49 | 65 | 76 | 97 |
完成一趟排序,其餘步驟類似
2.演算法例程
void sort_select(int unsort,int len)
}void adjustheap(int heap,int i,int len)
//如果存在右兒子節點 並且右兒子節點小於母節點
if(child_left+1heap[i])
//如果左右兒子節點都存在的時候,且小於母節點,這個時候在兒子節點中選取最小的節點
if(child_left+1heap[i]&&heap[child_left]>heap[i])
if(min!=i)
}//在堆中插入乙個元素
//排序
void sort_heap(int heap,int len)
}
1.理論思想
冒泡法排序的逐次比較交換,使大的數往下沉,小數向上冒,直至完成排序,冒泡法最壞的情況下是o(n^2),最好的情況下是o(n)。演算法實現簡單
例子為從小到大排序,
給定序列
第一趟排序(外迴圈)
第一次兩兩比較49 > 38交換(內迴圈)
交換前狀態| 49 | 38 | 65 | 97 | 76 | 13 | 27 | 49 |
交換後狀態| 38 | 49 | 65 | 97 | 76 | 13 | 27 | 49 |
第二次兩兩比較,49 < 65 不交換
第三次兩兩比較,65 < 97 不交換
第四次兩兩比較,97 > 76 交換
交換前狀態| 38 | 49 | 65 | 97 | 76 | 13 | 27 | 49 |
交換後狀態| 38 | 49 | 65 | 76 | 97 | 13 | 27 | 49 |
第五次兩兩比較,97 < 13 交換
交換前狀態| 38 | 49 | 65 | 76 | 97 | 13 | 27 | 49 |
交換後狀態| 38 | 49 | 65 | 76 | 13 | 97 | 27 | 49 |
依次第一次完成後
| 38 | 49 | 65 | 76 | 13 | 27 | 49 | 97 |
第二趟排序(外迴圈)
交換前狀態| 38 | 49 | 65 | 76 | 13 | 27 | 49 | 97 |
交換後狀態| 38 | 49 | 65 | 13 | 27 | 49 | 76 | 97 |
第三趟排序(外迴圈)
交換前狀態| 38 | 49 | 65 | 76 | 13 | 27 | 49 | 97 |
交換後狀態| 38 | 49 | 13 | 27 | 49 | 65 | 76 | 97 |
第四趟排序(外迴圈)
交換前狀態| 38 | 49 | 65 | 76 | 13 | 27 | 49 | 97 |
交換後狀態| 38 | 13 | 27 | 49 | 49 | 65 | 76 | 97 |
排序完畢輸出正確結果| 13 | 27 | 38 | 49 | 49 | 65 | 76 | 97 |
2.演算法例程
void sort_bubble(int unsort,int len)}}
}
1.理論思想
在待排序的n個記錄中任取乙個記錄(通常取第乙個記錄),把該記錄放入適當位置後,資料序列被此記錄劃分成兩部分。所有關鍵字比該記錄關鍵字小的記錄放置在前一部分,所有比它大的記錄放置在後一部分,並把該記錄排在這兩部分的中間(稱為該記錄歸位),這個過程稱作一趟快速排序。
給定序列
a),先把第一項[49]取出來,
用[49]依次與其餘項進行比較,
如果比[49]小就放[49]前邊,38 13 27 49都比[49]小,所以全部放到[49]前邊
如果比[49]大就放[49]後邊,65 97 76全部放到[49]後邊
一趟排完後變成下邊這樣:
排序前 49,38,65,97,76,13,27,49
排序後 38 13 27 49 49 65 97 76
b),對前半部分[38 13 27 49]繼續進行快速排序
c) 對後半部分[65 97 76]進行快速排序
依次遞迴實現b)和c)
排序完畢輸出正確結果| 13 | 27 | 38 | 49 | 49 | 65 | 76 | 97 |
2.演算法例程
int getpart(int *heap,int begin,int end)
3.複雜度分析
最壞的情況下:基本有序時,退化為氣泡排序,幾乎要比較n*n次,故為o(n*n)
資料結構 排序演算法
include include define maxitem 100 typedef char keytype 5 typedef int elemtype typedef struct rec elemnode maxitem 氣泡排序演算法 void bubblesort elemnode r,...
資料結構 排序演算法
直接插入排序是指將r i r n 插入到已經有序的r 1 r i 1 序列中。r 0 是乙個哨兵,起到作為邊界條件並作為暫存單元的作用。實際上,一切為簡化邊界條件而引入的附加節點 元素 均可稱為哨兵。例如單鏈表中的頭結點。對於有n個記錄的集合,要進行n 1趟排序。其最優時間複雜度是o n 平均時間複...
資料結構排序演算法
include using namespace std 輸入一組關鍵字序列分別實現下列排序 1.實現簡單選擇排序 直接插入排序和氣泡排序。2.實現希爾排序演算法。3.實現快速排序演算法。4.實現堆排序演算法。define maxsize 100 using namespace std typedef...