快速排序 - C语言
看了这本《数据结构与算法分析》中的快速排序。
写下自己理解后的代码,以备后用。
#include "stdio.h" void insertSort(int arr[], int N) { int j, tmp, P; for(P=1; P< N; P++) { tmp = arr[P]; for(j=P; j>0 && arr[j-1] > tmp; j-- ) arr[j] = arr[j-1]; arr[j] = tmp; } } void swap(int *first, int *second) { int tmp = *first; *first = *second; *second = tmp; } void printArr(int arr[], int N) { int i; for( i = 0; i < N; i++) { printf("%d\t", arr[i]); } printf("\n"); } int median3(int arr[], int left, int right) { int mid = (left + right)/2; if(arr[left] > arr[mid]) swap(&arr[left], &arr[mid]); if(arr[left] > arr[right]) swap(&arr[left], &arr[right]); if(arr[mid] > arr[right]) swap(&arr[mid], &arr[right]); swap(&arr[mid], &arr[right-1]); return arr[right -1]; } void quickSort(int arr[], int left, int right) { int coutoff = 3; if(left + coutoff < right) { int pivort = median3(arr, left, right); int i = left, j = right - 1; for(;;) { while(arr[++i] < pivort) {} while(arr[--j] > pivort) {} if(i < j) swap(&arr[i], &arr[j]); else break; } swap(&arr[i], &arr[right -1]); quickSort(arr, left, i - 1); quickSort(arr, i + 1, right); } else { insertSort(arr + left, right -left + 1); } } int main() { int test[10] = {5, 1, 10, 44, 20, 199, 18, 7, 24, 42}; printArr(test, 10); quickSort(test, 0, 9); // insertSort(test, 10) printArr(test, 10); return 0; }
主要步骤:
1,首先要写好swap,写好插入排序。
2,然后写好选择哨兵(中间值)的代码 median3,并且要记得隐藏哨兵节点(交换 mid 和 right - 1),这样left, right -1 , right 就是已经排序的了, 这样第一个节点和最后一个节点就不用进行检查了。
3,左侧检查实际上从left + 1 开始,右侧检查实际上从right-2开始。当然为了++i, --j 方便, 并且查到要交换的位置就是i,j的值,设置了初值为左:left,右:right-1。
4,循环找左侧比哨兵大的值,右侧找并哨兵小的值,如果有则交换,如果循环到最后相遇了那么就表示没有可以交换的了,i 和 j 都走到合适的位置。此时i 的位置就是比哨兵大的第一个位置, j 的位置就是比哨兵小的第一个位置。
5, 一次排序结束后当然记得将哨兵放回去, 交换 i 和 right-1。
6,然后再从节点位置分成两部分排序。[left ~ i-1] 和[ i+1 ~ right]。
当元素小于三个的时候直接用插入排序。
注意问题:插入排序参数是数组长度,而快速排序的参数是左侧索引和右侧索引。
如果理解有错误,大家多指正。