各種排序演算法及其C 實現

2021-06-20 03:54:53 字數 3826 閱讀 3532

基本思想:

每次將乙個待排序的資料元素,插入到前面已經排好序的數列中的適當位置,使數列依然有序;直到待排序資料元素全部插入完為止。

基本思想:

每一趟從待排序的資料元素中選出最小(或最大)的乙個元素,順序放在已排好序的數列的最後,直到全部待排序的資料元素排完為止。

基本思想:

兩兩比較待排序資料元素的大小,發現兩個資料元素的次序相反時即進行交換,直到沒有反序的資料元素為止。

排序過程:設想被排序的陣列a[1..n]垂直豎立,將每個資料元素看作有重量的氣泡,根據輕氣泡不能在重氣泡之下的原則,從下往上掃瞄陣列a,凡掃瞄到違反本原則的輕氣泡,就使其向上"漂浮",如此反覆進行,直至最後任何兩個氣泡都是輕者在上,重者在下為止。

基本思想:在當前無序區a[1..h]中任取乙個資料元素作為比較的"基準"(不妨記為x),用此基準將當前無序區劃分為左右兩個較小的無序區:a[1..i-1]和a[i+1..h],且左邊的無序子區中資料元素均小於等於基準元素,右邊的無序子區中資料元素均大於等於基準元素,而基準x則位於最終排序的位置上,即a[1..i-1]≤x.key≤a[i+1..h](1≤i≤h),當a[1..i-1]和a[i+1..h]均非空時,分別對它們進行上述的劃分過程,直至所有無序子區中的資料元素均已排序為止。

基本思想:堆排序是一樹形選擇排序,在排序過程中,將a[1..n]看成是一顆完全二叉樹的順序儲存結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關係來選擇最小的元素。

堆的定義: n個元素的序列k1,k2,k3,...,kn.稱為堆,當且僅當該序列滿足特性:

k[i]≤k[2i]  k[i]≤k[2i+1]  (1≤ i≤ [n/2])

堆實質上是滿足如下性質的完全二叉樹:樹中任一非葉子結點的關鍵字均大於(或小於)等於其孩子結點的關鍵字。如果乙個堆中根結點(稱為堆頂)的關鍵字最小,我們把它稱為小根堆。反之,若完全二叉樹中任一非葉子結點的關鍵字均大於等於其孩子的關鍵字,則稱之為大根堆。

排序過程:堆排序正是利用小根堆(或大根堆)來選取當前無序區中關鍵字最小(或最大)的記錄實現排序的。我們不妨利用大根堆來排序。每一趟排序的基本操作是:將當前無序區調整為乙個大根堆,選取關鍵字最大的堆頂記錄,將它和無序區中的最後乙個記錄交換。這樣,正好和直接選擇排序相反,有序區是在原記錄區的尾部形成並逐步向前擴大到整個記錄區。

選取排序方法需要考慮的因素:

(1) 待排序的元素數目n;

(2) 元素本身資訊量的大小;

(3) 關鍵字的結構及其分布情況;

(4) 語言工具的條件,輔助空間的大小等。

小結:(1) 若n較小(n <= 50),則可以採用直接插入排序或直接選擇排序。由於直接插入排序所需的記錄移動操作較直接選擇排序多,因而當記錄本身資訊量較大時,用直接選擇排序較好。

(2) 若檔案的初始狀態已按關鍵字基本有序,則選用直接插入或氣泡排序為宜。

(3) 若n較大,則應採用時間複雜度為o(nlog2n)的排序方法:快速排序、堆排序或歸併排序。快速排序是目前基於比較的內部排序法中被認為是最好的方法。

(4) 在基於比較排序方法中,每次比較兩個關鍵字的大小之後,僅僅出現兩種可能的轉移,因此可以用一棵二叉樹來描述比較判定過程,由此可以證明:當檔案的n個關鍵字隨機分布時,任何借助於"比較"的排序演算法,至少需要o(nlog2n)的時間。

#include "sort.h"

#include using namespace std;

sort::sort(void)

sort::~sort(void)

//氣泡排序

//原理:每趟排序是通過比較兩兩相鄰的元素,大的向後移動,一趟

//完後,最大的移動到最後,共需要size-1趟排序,特殊情況下,某趟未

//移動任何元素,則說明序列已然有序,則排序完畢,此時趟數data[j + 1])}}

print(data,size);

}//選擇排序

//原理:每次選擇都是從序列中選擇最小的元素,放到序列前面,共需size-1次選擇

void sort::xuanze(int data,int size)

if (k != i - 1)

swap(data,k,i - 1);

}print(data,size);

}//直接插入排序

//原理:將序列分為有序和無序兩部分,每次排序需要將無序區的乙個元素

//插入到有序區的合適位置,需要size-1次排序

void sort::charu(int data,int size)

data[j + 1] = temp;

}print(data,size);

}//歸併排序

//原理:一次歸併可描述為,將乙個序列分成兩組,將這兩組歸併為乙個有序的新序列,

//歸併排序就是遞迴的進行上述操作(遞迴棧的最底部是將序列分成了[乙個元素]、[乙個元素]

//這樣的兩組),我的表達能力也就到這了

void sort::guibing(int data,int size)

void sort::mergesort(int data,int first,int last)

}//歸併兩個陣列[first,mid]、[mid+1,last],最後合併為乙個有序的陣列[first,last]

void sort::merge(int data,int first,int mid,int last)

while (index1 <= mid)

temp[k++] = data[index1++];

while (index2 <= last)

temp[k++] = data[index2++];

for (int i = 0; i < k; i++)

data[first + i] = temp[i];

delete temp;

}//快速排序

//原理:一次快排可描述為,將序列分成三部分[左邊組都小於中間數]、[中間數]、[右邊組都大於中間數]

//快排就是再遞迴的對左邊組和右邊組進行上述操作

void sort::kuaipai(int data,int size)

void sort::quicksort(int data,int left,int right)

}//一趟分組,執行完後分為左右兩組,左組都小於中間數,右組都大於中間數

int sort::partion(int data,int left,int right)

//最後將中間數放到真正的中間位置,此時leftindex=rightindex

data[leftindex] = temp;

//返回中間數下標,以便對左右兩組繼續排序

return leftindex;

}//希爾排序

//原理:屬於一種改進的插入排序,將序列按照特定的步長分成若干個子串行,

//對各個子串行進行插入排序,然後再按照更小的步長分成若干子串行,對子序列排序,

//......最後一步的步長為1,這樣最後一步則「等於」直接插入排序了,此時的序列是

//基本有序的,直接插入排序對有序序列的排序效率是很高的

void sort::xier(int data,int size)

if (j != i - d)

data[j + d] = temp; }}

print(data,size);

}//交換陣列中兩個元素

void sort::swap(int data,int i,int j)

void sort::print(int data,int size)

{ for (int i = 0; i < size; i++)

{cout<(5) 當記錄本身資訊量較大時,為避免耗費大量時間移動記錄,可以用鍊錶作為儲存結構。

各種排序演算法C 實現

各種排序演算法的實現 交換函式 void swap int list,int low,int high 小於函式 bool lt const int low,const int high 插入排序 穩定 原理 插入排序逐個處理待排序的記錄。每個新記錄與前面已排序的子串行進行比較,將它插入到子串行中正...

各種排序演算法C 實現

include include include using namespace std 插入排序 void insertsort int num,int len 氣泡排序 void bubblesort int num,int len if flag break 選擇排序 void selectso...

各種排序演算法的C 實現

include include include include include include using namespace std void bubble vector a 氣泡排序 void insert vector a 插入排序 void shellsort vector a 希爾排序 i...