深入理解快排
参考
https://blog.csdn.net/lxk2017/article/details/102779042
https://blog.csdn.net/liuyi1207164339/article/details/50827608
仅仅作为记录
深入理解快排
首先说一下核心点:
从序列中找出一个基准值,然后 将小于基准值的置于左边,大于基准值的置于右边,关键点在于中间值的寻找
最坏复杂度为 On2 平均为 logn , 不稳定算法
第一种:直接取首或者尾作为 中间值
缺点:当序列本身是有序的,每次分割的子序列 范围差异大
代码
int getSort(int array[], int start, int end);
int getMidValue(int array[], int start, int end);
void fastSort(int array[], int start, int end) {
if( start < end ) {
int mid = getSort(array, start, end);
fastSort(array, start, mid -1 );
fastSort(array, mid + 1, end);
}
}
int getMidValue(int array[], int start, int end) {
return end;
}
int getSort(int array[], int start, int end) {
int mid = getMidValue(array, start, end);
int value = array[mid];
while ( start < end ) {
while( ( start < end ) && ( array[start] < value )) {
start++;
}
if( start < end ) {
swap(array[start], array[end]);
end--;
}
while( ( start < end ) && ( array[end] > value )) {
end--;
}
if( start < end ) {
swap(array[start], array[end]);
start++;
}
}
array[start]=value;
return start;
}
第二种 : 使用随机取中间值
就是使用rand()%(high - low) + low; ,每次来选取随机中间值。由于中间值是随机的,所以劣势的 子序列范围也不会出现。基本满足需求
int getSort(int array[], int start, int end);
int getMidValue(int array[], int start, int end);
void fastSort(int array[], int start, int end) {
if( start < end ) {
int mid = getSort(array, start, end);
fastSort(array, start, mid -1 );
fastSort(array, mid + 1, end);
}
}
int getMidValue(int array[], int start, int end) {
srand((unsigned)time(NULL));
int pivotPos = rand()%(end - start) + start;
swap(array[pivotPos], array[end]);
return end;
}
int getSort(int array[], int start, int end) {
int mid = getMidValue(array, start, end);
int value = array[mid];
while ( start < end ) {
while( ( start < end ) && ( array[start] < value )) {
start++;
}
if( start < end ) {
swap(array[start], array[end]);
end--;
}
while( ( start < end ) && ( array[end] > value )) {
end--;
}
if( start < end ) {
swap(array[start], array[end]);
start++;
}
}
array[start] = value;
return start;
}
第三种 :使用三值取中
就是 start mid end,对三个进行 小 中 大 排序
对于一个 序列 :
举例:待排序序列为:8 1 4 9 6 3 5 2 7 0
左边为:8,右边为0,中间为6.
那么中间 值就是 6
然后我们把 6作为 start下标值,进行排序
那么中间值算法实现起来
int getSort(int array[], int start, int end);
int getMidValue(int array[], int start, int end);
void fastSort(int array[], int start, int end) {
if( start < end ) {
int mid = getSort(array, start, end);
fastSort(array, start, mid -1 );
fastSort(array, mid + 1, end);
}
}
int getMidValue(int array[], int start, int end) {
int mid = start + (end - start)/2;
if( start > end ) {
swap(array[start], array[end]); //end is high
}
if( mid > end ) {
swap(array[mid], array[end]); //mid < high
}
if( mid > start ) {
swap(array[mid], array[start]); // archeive mid start end
}
return array[start];
}
int getSort(int array[], int start, int end) {
int value = getMidValue(array, start, end);
while ( start < end ) {
while( ( start < end ) && ( array[end] > value )) {
end--;
}
if( start < end ) {
swap(array[start], array[end]);
start++;
}
while( ( start < end ) && ( array[start] < value )) {
start++;
}
if( start < end ) {
swap(array[start], array[end]);
end--;
}
}
array[start] = value;
return start;
}
一个圆,圆内是你会的,圆外是你不知道的。而当圆越大,你知道的越多,不知道的也越多了