排序算法之二快速排序

 算法思想(分治)

1、从数组中取出一个数作为基准数;

2、分区,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边;

3、对左右区间重复第二步,直到各区间只有一个数。

最差时间复杂度:每次选取的基准数都为最大(或最小元素),因此只划分了一个分区,需要进行n-1次划分才能结束,故复杂度为O(n^2);

最优时间复杂度:每次选取的基准数都是中位数,因此每次都划分出两个分区,需要进行logn次递归,故时间复杂度为O(nlogn);

平均时间复杂度:O(nlogn),稳定性:不稳定。

算法步骤(参考:挖坑填数

1、令 low = left,high = right,选取一个基准数,将它赋值给 flag,那么在这个基准数的位置上就挖了一个坑 arr [ low ] ;

2、high -- 从后往前找比它小的数,找到后将它填到坑 arr [ low]中,此时在这个数所在的地方形成了一个新坑 arr [ high ] ;

3、low ++从前往后找比它大的数,找到后将它填到坑 arr [ high ]中, 此时在这个数所在的地方形成了一个新坑 arr [ low] ;

4、重复2、3两步,直到 low = high,将基准数 flag 填入 arr [ low ] 中,此时flag左边的数全部小于flag,右边的数全部大于 flag ;

5、对 flag 左边的数和右边的数分别递归调用快速排序

6、返回排序好的数组

function quickSort(arr,left,right){
    if(left == right){
        return arr;
    }
    if(left < right){
        var low = left,high = right;
        //arr[low]是第一个坑,将它设置为基准点flag
        var flag = arr[low];
        while(low < high){
            //从后往前找比flag小的数
            while(low < high && arr[high] >= flag){
                high --;
            }
            //找到比flag小的数之后,用这个数把之前arr[left]的坑填上
            //那么这个数所在的位置arr[right]就成了一个新的坑
            if(low < high){
                arr[low] = arr[high];
                low ++;
            }
            //从前往后找比flag大的数
            while(low < high && arr[low] <= flag){
                low ++;
            }
            //找到比flag大的数之后,用这个数把arr[right]的坑填上
            //那么这个数所在的位置arr[left]就又成了一个新的坑
            if(low < high){
                arr[high] = arr[low];
                high --;
            }
        }
        //当left和right两个指针碰头后,将基准数保存到left = right的地方
        //此时flag左边的数全部小于flag,右边的数全部大于flag
        arr[low] = flag;
        //递归调用
        quickSort(arr,left,low - 1);
        quickSort(arr,low + 1,right);
    }
    return arr;
}

 

posted @ 2018-07-31 14:12  叶子叶子耶  阅读(134)  评论(0编辑  收藏  举报