深入理解快排

参考
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;
}
posted @ 2021-05-26 17:41  make_wheels  阅读(156)  评论(0编辑  收藏  举报