首页 > 代码库 > 快速排序
快速排序
// 快速排序的实现版本// 其中median3 是从头,尾部,和中部取出值,再相互比较// 得到枢纽元#include <stdio.h>#define Cutoff (7)int median3(int A[] , int Left , int Right);void Qsort(int A[] , int Left , int Right);void Swap(int *A , int *B);void InsertSort(int *A , int N);int main(int argc, const char * argv[]) { int A[15] = {9,8,7,6,5,4,3,2,1,9,8,7,6,5,4}; Qsort(A, 0, 14); //InsertSort(A, 15); for (int i = 0 ; i < 15 ; i++) printf("%d " , A[i]); return 0;}int median3(int A[] , int Left , int Right){ int center = (Left + Right) / 2 ; if (A[Left] > A[center]) Swap(&A[Left] , &A[center]); if (A[Left] > A[Right]) Swap(&A[Left] , &A[Right]); if (A[center] > A[Right]) Swap(&A[center] , &A[Right]); /* Invariant: A[Left] < A[center] < A[Right] */ Swap(&A[center], &A[Right -1]); //此时A[Right]已经在合适的位置了,就 //把枢纽元放在A【Right -1]的位置上 return A[Right - 1]; return 0 ;}void Qsort(int A[] , int Left , int Right){ int i , j ; int pivot ; if(Left + Cutoff <= Right) { i = Left; j = Right - 1; pivot = median3(A, Left, Right); for ( ; ; ) { while (A[++i] < pivot) ; while (A[--j] > pivot) ; if(i < j ) Swap(&A[i], &A[j]); else break; } Swap(&A[i], &A[Right - 1]); /* Restore piovt*/ Qsort(A, Left, i-1); Qsort(A, i + 1, Right); } else /* 小于10的时候,用插入排序代替快速排序 */ InsertSort(A + Left , Right - Left + 1);}void Swap(int *A , int *B){ int temp = *A ; *A = *B ; *B = temp ;}void InsertSort(int A[] , int N){ int i , j ; int Tmp ; for (i = 1 ; i < N ; i++) { Tmp = A[i]; for (j = i ; j > 0 && A[ j - 1 ] > Tmp; j --) A[j] = A[j - 1 ]; //使用数据移动代替数据交换,很重要的技巧 A[j] = Tmp ; }}/* *************************************************快速排序总结 ***************************************************//* * 1 选取枢纽元 * 选取第一个或最后一个作为枢纽元 // 当输入数据是预排序的,则会一直产生很差的 // 划分,而这经常发生,所以,不能采用 * 随机选取一个枢纽元 // 代价有点大 * 三数中值分割法 // 选取第一个,最后一个和中间一个,然后排序 // 选取中间的那个数作为枢纽元,由于,第一个和 // 最后一个已经在何时的位置了,所以,将中间的那个数同A【Right-1】交换即可 // 函数median3 即选出枢纽元 // * 2 分割策略 * i= -1 , j = 0 ,然后追赶 不是一个好策略 * i = 0 , j = N -1 , 然后迎面相迎 是一个好策略 * 3 如何处理与枢纽元相等的元素 * 当 i 和 j 遇到与枢纽元相等的时候,是否应该停止? * 1 不停止 如果不停止的话,如果有很多相等的,会产生很坏的划分,还需要额外的 判断是否到头了,增加了开销 * 2 停止 做了n / 2 次交换,但是i 和 j 在中间交错,产生一个好的划分 ** 结论: 我们应该遇到相等就停下 * 4 当遇到小数组的时候,改变递归快速排序,改用插入排序 插入排序在N ( 5 15)的时候速度比快速排序快 推荐N= 10 * 5 时间复杂度分析 看算法导论的时间复杂度分析 */
快速排序
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。