快速排序
Posted 思而不学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速排序相关的知识,希望对你有一定的参考价值。
一、分而治之
什么十快速排序算法的最好情况?
每次正好中分:T(N) = O(NlogN)
void Quicksort(ElementType A[], int N) { pivot = 从A[]中选一个主元; 将S = { A[] \\ pivot } 分成2个独立子集: A1 = { a属于S | a≤ pivot } 和 A2 = { a属于S | a≥ pivot }; A[] = Quicksort(A1, N1) U { pivot} U Quicksort(A2, N2); }
选主元
- 随机取pivot?rand()函数不便宜啊!
- 取头、中、尾的中位数
- 例如8、12、3的中位数就是8
- 测试一下pivot不同的取法对运行速度有多大影响?
ElementType Median3(ElementType 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]); /* A[Left] <= A[Center] <= A[Right] */ Swap(&A[Center], &A[Right-1]); /* 只需要考虑A[Left+1] ... A[Right-2] */ return A[Right-1]; }
小规模数据的处理
- 快速排序的问题
- 用递归。。
- 对小规模的数据(例如N不到100)可能还不如插入排序快
- 解决方案
- 当递归的数据规模充分小,则停止递归,直接调用简单排序(例如插入排序)
- 在程序中定义一个Cutoff的阈值 -- 课后去时间一下,比较不同的Cutoff对效率的影响
实现算法
void Quicksort(ElementType A[], int Left, int Right) { if(Cutoff <= Right-Left) { Pivot = Median3(A, Left, Right); i = Left; j = Right - 1; 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]); Quicksort(A, Left, i-1); Quicksort(A, i+1, Right); } else Insertion_Sort(A+Left, Right-Left+1); } void Quick_Sort(ElementType A[], int N) { Quicksort(A, 0, N-1); }
以上是关于快速排序的主要内容,如果未能解决你的问题,请参考以下文章