快速排序

算法思路

选择一个数字 povit = array[low] 为关键字
目的就是为了确定关键字所在最终结果中的位置
通过遍历分区,左分区小于关键字,右分区大于关键字,关键字位置确定

注意

递归时一直都是操作的array数组,分区是array的一部分,没有将分区作为一个新数组。
分区是用lowhigh再加上关键字位置index来计算的

时间复杂度

快速排序是不稳定的
平均:O(nlogn)
最坏:O(n²);数组本身有序

步骤详解

  • 初始数组
var array = [49, 25, 32, 95, 64, 71, 13]

初始数组

  • 选中最低位为关键字,关键字被记录以后不再关注array[0]的值,最后将关键字放到居中(左边数字<关键字<右边数字)的位置,即时最终结果该元素所在位置
pivot = array[0]
low = 0
high = 6

选中关键字

  • 从右向左遍历,遇到比关键字小的则替换,此时low = 1high = 6array[6]不再被关注
while (low < high && array[high] >= pivot) {
    high--;
}
array[low] = array[high];

第一次替换

  • 从左向右遍历,遇到比关键字大的则替换,此时low = 3high = 6
while (low < && array[low] <= pivot) {
    low++;
}
array[high] = array[low];

第二次替换

  • 再从右向左遍历,直到low == high
while (low < high) {
    while (low < high && array[high] <= pivot) {
        high--;
    }
    array[low] = array[high];
    while (low < && array[high] >= pivot) {
        low++;
    }
    array[high] = array[low];
}

low == high

  • 最终确定关键字的位置并将关键字赋值到此处,返回该位置;得到了新的数组,此时关键字所在就是最终数组的位置
array[low] = pivot
return low;

返回关键字的位置

  • 接下来对对分区数组重复以上步骤,先左后右,一直在改变array,每次都能将关键字所在的最终位置确定

最小分区

  • 退出循环
  1. 关键字位置为 array[low] ,左分区为空,递归时 low > high
  2. 关键字位置为 array[high] ,又分区为空,递归时 low > high
  3. 关键字位置为 low + 1 或者 high -1 ,左或右分区只有一个元素,递归时 low == high

完整代码

function Partition(array, low, high) {
    var pivot = array[low];
    while (low < high) {
        while (low < high && array[high] >= pivot) {
            high--;
        }
        array[low] = array[high];
        while (low < high && array[low] <= pivot) {
            low++;
        }
        array[high] = array[low];
    }

    array[low] = pivot;
    return low;
}

function QuickSort(array, low, high) {
    if (low < high) {
        var index = Partition(array, low, high);
        QuickSort(array, low, index - 1);
        QuickSort(array, index + 1, high);
    }
}

var array = [49, 25, 32, 95, 64, 71, 13];
QuickSort(array, 0, array.length - 1);
console.log(array);

结果

其它写法1

function QuickSort(array, low, high) {
    if (low < high) {
        //划分
        pivot = array[low];
        i = low;
        j = high;
        while (i < j) {
            while (i < j && array[j] >= pivot) {
                j--;
            }
            array[i] = array[j]
            while (i < j && array[i] <= pivot) {
                i++;
            }
            array[j] = array[i];
        }
        //确认关键字位置
        array[i] = pivot;

        //对分区进行快排
        QuickSort(array, low, i - 1);
        QuickSort(array, i + 1, high);
    }
}

var array = [49, 25, 32, 95, 64, 71, 13];
QuickSort(array, 0, array.length - 1)

结果

其它写法2

//分区
function Partition(array, length, start, end) {

    if (array == null || length <= 0 || start < 0 || end >= length) {
        consol.log('Invalid Parameters')
    }
    //生成随机数
    var index = RandomInRange(start, end);
    //交换
    Swap(array[index], array[end]);

    var small = start - 1;
    for (index = start; index < end; ++index) {
        if (data[index] < data[end]) {
            ++small;
            if (small != index) {
                Swap(array[index], array(small));
            }
        }
    }

    ++small;
    Swap(array[small], array[end]);

    return small;

}

function QuickSort(array, length, start, end) {
    if (start == end) {
        return;
    }
    var index = Partition(array, length, start, end);
    if (index > start) {
        QuickSort(array, length, start, end);
    }
    if (index < end) {
        QuickSort(array, length, index + 1, end);
    }

}

var array = [49, 25, 32, 95, 64, 71, 13]
QuickSort(array, array.length, 0, array.length - 1)

参考:
《剑指offer》
《数据结构(C语言版)》 ——严蔚敏 吴伟民

posted @ 2018-07-20 16:07  言凡  阅读(393)  评论(0编辑  收藏  举报