經典的幾種排序方式

2021-08-11 15:39:09 字數 3792 閱讀 7880

所謂排序就是整理檔案中的記錄,使之按關鍵字遞增(或遞減)次序排列起來。

穩定排序與不穩定排序:

假設 ki = kj ,且排序前序列中 ri 領先於 rj ;

若在排序後的序列中 ri 仍領先於 rj ,則稱排序方法是穩定的。

若在排序後的序列中 rj 仍領先於 ri ,則稱排序方法是不穩定的。

例:序列 3 15 8 8 6 9

若排序後得 3 6 8 8 9 15 穩定的#兩個8 不同順序

若排序後得 3 6 8 8 9 15 不穩定的

根據排序過程中待排序記錄是否全部放置在記憶體中,排序分為內排和外排。

內部排序: 指的是待排序記錄存放在計算機隨機儲存器中進行的排序過程。

外部排序: 指的是待排序記錄的數量很大,以致記憶體一次不能容納全部記錄,在排序過程中尚需對外存進行訪問的排序過程。

演算法的複雜性:體現在執行該演算法時的計算機所需資源的多少上,計算機資源最重要的是時間和空間(即暫存器)資源,因此複雜度分為時間和空間複雜度。

輔助空間:輔助空間是評價排序演算法的乙個重要指標,輔助空間是指除了存放待排序資源之外,執行演算法所需要的其他儲存空間。

時間複雜度:簡單的說就是程式迴圈執行的總的次數。演算法的時間複雜度是乙個函式,它定量描述了該演算法的執行時間。時間複雜度常用大o符號表述,即o(f(n))。

按照排序過程中所依據的原則的不同可以分類為:

►插入排序

直接插入排序 希爾排序

►交換排序

氣泡排序 快速排序

►選擇排序

簡單選擇排序 堆排序

►歸併排序

►基數排序

介紹幾種已經掌握的排序方法:

直接插入排序:

對於給定的一組記錄,初始時假定第乙個記錄自成乙個有序的序列,其餘的記錄為無序序列;接著從第二個記錄開始,按照記錄的大小依次將當前處理的記錄插入到其之前的有序序列中,直至最後乙個記錄插入到有序序列為止。

例:將 29 18 87 56 3 27 按由小到大排序

① (29) (18 87 56 3 27)

② (18 29) (87 56 3 27)

③ (18 29 87) (56 3 27)

④ (18 29 56 87) (3 27)

⑤ ( 3 18 29 56 87) (27)

⑥ (3 18 27 29 56 87)

具體的程式看下:(由於標頭檔案寫了不好上傳 請用時自行加上 下面也是)

int main()

; length = sizeof(a)/sizeof(a[0]);

for(i = 1; i < length; i++)

else }

a[j+1] = temp;

}

for(i = 0; i < length; i++)

printf("\n");

return 0;

}

穩 定 性:穩定

時間複雜度: o(n^2)

(1)初始資料正序,總比較次數:n-1

(2)初始資料逆序,總比較次數:(n2+n-1)/2= o(n2)

(3)初始資料無序,第i趟平均比較次數(i+1)/2,總次數為:(n2+3n)/4=o(n2)

(4)可見,原始資料越趨向正序,比較次數和移動次數越少。

希爾排序:

希爾排序也稱為「縮小增量排序」,基本原理是:首先將待排序的元素分為多個子串行,使得每個子序的元素個數相對較少,對各個子序分別進行直接插入排序,待整個待排序序列「基本有序後」,再對所有元素進行一次直接插入排序。

希爾排序的特點:

時間複雜度:希爾排序的時間複雜性在o(nlog2n)和o(n2 )之間,大致為o(n1.3)。

穩 定 性:不穩定

具體程式如下:

int main()

; int length,i,j,temp,gap;

length = sizeof(a)/ sizeof(a[0]);

for(gap = length/2; gap > 0; gap /= 2)

a[j+gap]= temp;

} }

for(i = 0; i < length; i++)

printf(「\n」);

return 0;

}快速排序:

快速排序是一種非常高效的排序方法,採用「分而治之」的思想,把大的拆分為小的,小的在拆分為更小的。

原理是:對於一組給定的記錄,通過一趟排序後,將原序列分為兩部分,其中前部分的所有記錄均比後部分的所有記錄小,然後再依次對前後兩部分的記錄進行快速排序,遞迴該過程,直到序列中的所有記錄均為有序為止

快速排序特點:

穩 定 性:不穩定

平均時間複雜度: o(nlog2n)

程式如下:

void sort(int *a,int low,int high)

while(i < j)

if(i < j)

while(i < j && a[i] < index)

if(i < j)

}a[i] = index;

sort(a,low,i - 1);

sort(a,i + 1,high);void quicksort(int a, int length)

int main()

; int i;

int length = sizeof(a) /sizeof(a[0]);

quicksort(a,length);

for(i = 0; i < length; i++)

printf(「\n」);

return 0;

}歸併排序:

利用遞迴與分治技術將資料序列劃分為越來越小的半子表,再對半子表排序,最後再用遞迴步驟將排好序的半子表合併成為越來越大的有序序列。

原理如下:對於給定的一組記錄,首先將兩個相鄰的長度為1的子串行進行歸併,得到n/2個長度為2或者1的有序子串行,在將其兩兩歸併,反覆執行此過程,直到得到乙個有序的序列為止。

例:將49 38 65 97 76 13 27由小到大排序

初始化關鍵字:[49] [38] [65] [97] [76] [13] [27]

一趟歸併後: [38 49] [65 97] [13 76] [27]

二趟歸併後: [38 49 65 97] [13 27 76]

三趟歸併後: [13 27 38 49 65 76 97]

歸併排序特點:

平均時間複雜度: o(nlog2n)

穩 定 性: 穩定

程式如下:

void merging(int a,int begin,int mid,int end)

while(i <= mid)

tmp[k++] = a[i++];

while(j <= end)

tmp[k++] = a[j++];

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

free(tmp);}

void merge_sort(int a,int begin,int end)

int main()

; printf(「enter 10 num…\n」);

for(i = 0;i < 10;i++)

length = sizeof(a)/sizeof(int);

merge_sort(a,0,length - 1);

for(i = 0;i < length;i++)

return 0;

幾種經典排序演算法

據說第乙個正確的快排演算法程式是在快排思想提出後的兩三年才有人寫出來,我們都是站在巨人的肩上碼 啊。演算法 一趟排序為,選出乙個哨兵元素,可以為左邊第乙個,然後從序列的最左邊開始遍歷,選出比哨兵元素小的元素下標,標記為r,從序列的左邊開始遍歷,選出比哨兵元素大的元素下邊,標記為l,然後r l下邊的元...

幾種經典排序演算法的總結

假期即將結束,用最後這兩天溫習一下幾種經典排序演算法,總結一下,如有錯誤,請不吝指出 1.基本概念 1 穩定排序 當待排元素中有相同元素時,排序完後這些相同元素的相對位置與原來一致。例如 1a 2a,5,4,1b 3,2b 排序完後 1a 1b,2a 2b,3,4,5 2 原地排序 指排序時只需要使...

Hive的幾種排序方式

記錄hive的幾種常見的排序方式 order by 普通排序,通過order對欄位進行降序或者公升序 select from emp order by sal sort by 對每乙個reduce的結果進行排序,為了看出效果,我們多設定幾個reduce,檢視每個reduce的結果是否是排序的。set...