本帖依據學習進度持續更新
《資料結構與演算法分析-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開始會多加乙個判斷得不償失 每次迴圈所要加入的元素,如果大於前乙個元素,就直接加入,否則就將將前面已...