快速排序
算法思路
选择一个数字
povit = array[low]
为关键字
目的就是为了确定关键字所在最终结果中的位置
通过遍历分区,左分区小于关键字,右分区大于关键字,关键字位置确定
注意
递归时一直都是操作的
array
数组,分区是array
的一部分,没有将分区作为一个新数组。
分区是用low
和high
再加上关键字位置index
来计算的
时间复杂度
快速排序是不稳定的
平均:O(nlogn)
最坏:O(n²)
;数组本身有序
步骤详解
- 初始数组
var array = [49, 25, 32, 95, 64, 71, 13]
- 选中最低位为关键字,关键字被记录以后不再关注
array[0]
的值,最后将关键字放到居中(左边数字<关键字<右边数字)的位置,即时最终结果该元素所在位置
pivot = array[0]
low = 0
high = 6
- 从右向左遍历,遇到比关键字小的则替换,此时
low = 1
,high = 6
,array[6]
不再被关注
while (low < high && array[high] >= pivot) {
high--;
}
array[low] = array[high];
- 从左向右遍历,遇到比关键字大的则替换,此时
low = 3
,high = 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];
}
- 最终确定关键字的位置并将关键字赋值到此处,返回该位置;得到了新的数组,此时关键字所在就是最终数组的位置
array[low] = pivot
return low;
- 接下来对对分区数组重复以上步骤,先左后右,一直在改变
array
,每次都能将关键字所在的最终位置确定
- 退出循环
- 关键字位置为
array[low]
,左分区为空,递归时low > high
- 关键字位置为
array[high]
,又分区为空,递归时low > high
- 关键字位置为
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语言版)》 ——严蔚敏 吴伟民