幾種排序演算法

2021-06-28 11:24:40 字數 3265 閱讀 3965

本帖依據學習進度持續更新

《資料結構與演算法分析-c語言描述》學到第七章,是時候該系統的學習一下排序演算法了。首先學到的是插入排序,演算法就不贅述了,書上部落格上到處都有。書上的兩個定理還不太明白:

插入排序

定理7.1

n個互異數的陣列的平均逆序數是n(n-1)/4。

定理7.2

通過交換相鄰元素進行排序的任何演算法平均需要ω(n^2)時間。

插入排序的演算法複雜度應該為o(n^2)才對。

下面是我的測試用例:

void insertionsort(elementtype a, int n)

}

希爾排序

希爾排序的最後一樣增量是1,所以是直接插入排序,但移動次數比直接插入排序少,代入陣列測試:

#include#define elementtype int

void shellsort(elementtype a, int n)

}void main()

; shellsort(a, 13);

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

printf("%d ", a[i]);

}

堆排序

我們為了找出一列數第k個最小的數引入二叉堆,最小堆總能從根節點輸出最小值,一直使用deletemin函式就能輸出一列排序好的數,因為最小值最先輸出,所以這個數列是遞減的。由此我們可以得出如果建乙個最大堆,使用deletemax函式就能輸出一列遞增的序列。時間複雜度為o(nlogn)。

#include#define leftchild(i) (2*i+1)

void swap(int *a, int *b)

void percdown(int a, int i, int n)

a[i] = tmp;

}void heapsort(int a, int n)

}void main()

; heapsort(a, 13);

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

printf("%d ", a[i]);

}

歸併排序

該演算法是經典的分治策略,基本的操作是合併兩個已排序的表,放到第三個表中。而已排序的表又可以通過歸併排序本身遞迴得到。

#include#include#define elementtype int

void merge(elementtype a, elementtype tmp, int lpos, int rpos, int rightend)

void msort(elementtype a, elementtype tmp, int left, int right)

}void mergesort(elementtype a, int n)

else

printf("no space for tmp array");

}void main()

; mergesort(a, 13);

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

printf("%d ", a[i]);

}

快速排序

書上的一種以三數中值作為基準值的快速排序,當陣列長度小於3的時候選用插入排序,用的遞迴實現。

#include#define cutoff 3

void swap(int *a, int *b)

void insertionsort(int a, int n)

}int median3(int a, int left, int right)

void qsort(int a, int left, int right)

while(a[--j] > pivot){}

if(i < j)

swap(&a[i], &a[j]);

else

break;

} swap(&a[i], &a[right - 1]);

qsort(a, left, i - 1);

qsort(a, i + 1, right);

} else

insertionsort(a + left, right - left + 1);

}void quicksort(int a, int n)

void main()

;

quicksort(a, 13);

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

printf("%d ", a[i]);

}

下面是自己寫的以第乙個數作為基準值的快速排序。實際上這中基準值的選取是非常糟糕的,如果輸入是預排序的或是反序的,第一次分割就總是分割到一邊,時間複雜度為o(n^2),僅作為程式設計練習。

#include#define cutoff 3

void swap(int *a, int *b)

void qsort(int a, int left, int right)

else

break;

} swap(&a[i], &a[right]);

qsort(a, left, i - 1);

qsort(a, i + 1, right); }}

void quicksort(int a, int n)

void main()

;

quicksort(a, 13);

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

printf("%d ", a[i]);

}

//以第乙個元素作為基準,單向劃分的快速排序

#includevoid swap(int *a, int *b)

void qsort(int a, int left, int right)

swap(&a[pos], &a[left]);

qsort(a, left, pos - 1);

qsort(a, pos + 1, right);

}void quicksort(int a, int n)

幾種排序演算法

幾種比較常見的排序演算法 第一種 函式功能 雙向氣泡排序 2013.7.8 時間複雜度o n 2 include void mp int array,int n if mmax 0 沒有記錄交換,掃瞄結束 break bmax mmax for i bmax 1 i bmin i 此次掃瞄使輕氣泡上...

幾種排序演算法

最近一直在複習演算法,在經歷了四次面試之後,還沒有找到適合自己的工作 暫時歇一歇,準備冬天去北京創業一條街吹泡泡去。在面試過程中主要提及的就是對於排序演算法的疑問 主要針對以下幾種排序演算法 1,氣泡排序 2,插入排序 3,選擇排序 4,希爾排序 5,歸併排序 6,快速排序 7,堆排序 對於基數排序...

幾種排序演算法

插入排序 void sort int a,inta size a j key printf n print a,a size 插入排序的設計思想就是按照從陣列a 1 開始 當然也可以從0開始只不過從0開始會多加乙個判斷得不償失 每次迴圈所要加入的元素,如果大於前乙個元素,就直接加入,否則就將將前面已...