「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」
三言两语
关键点:时间复杂度为O(nlogn) 、递归、分而治 基础算法是必须要搞懂的,不然每次面试的时候被问起来,却一脸茫然。
解题思路
1、从数组中随机找出一个基准数
-
基准数怎么选择?
1、选择第一个元素
2、选择中间数
3、随机选取一个数
2、分别设置2个指针,一个指向最后一位,一个指向第一位,先从右往左找比基准数小的值,再从左往右找比基准数大的值,然后置换,直到左右指针指向同一位置即结束一轮
3、第二轮,重复上述过程后基准数左侧的数组,和基准数右侧的数组
4、使用递归方法,重复每轮的操作,直到基准值的左侧只有一个数据则结束。
解题过程
题目:数组ary = [14, 7, 6, 19, 10, 16], 是用快速排序算法进行排序
14 7 6 19 10 16 pivot =14
第一轮:
1、pivot = 14 ,从右到左,j=4时,10<14;从左到右,i=3时,19>14;那么交换10和19,
2、继续遍历时,i>j了,所以在i=3时暂停,pivot值与ary[i]置换,那么基准数左侧都小于14,右侧都大于14。
所以 pivot =14时 ==>基准位置是3,结果:10 7 6 14 19 16
pivot=10 ==>基准位置:2 结果:6 7 10 14 19 16
pivot=6 ==>基准位置: 0 结果:6 7 10 14 19 16
pivot=19 ==> 基准位置:5 结果:6 7 10 14 16 19
代码实现
Golang版本
func sortKuaisu(ary []int) {
sortKuaisu_sort(ary, 0, len(ary)-1)
for _, v := range ary {
fmt.Print(v, ",")
}
}
func sortKuaisu_getIndex(ary []int, low, high int) int {
pivot := ary[low] // 第一位为基准数
i := low
j := high
for i < j {
for ary[j] >= pivot && i < j {
j--
}
for ary[i] <= pivot && i < j {
i++
}
ary[i], ary[j] = ary[j], ary[i]
}
ary[i], ary[low] = ary[low], ary[i]
return i
}
func sortKuaisu_sort(ary []int, low, high int) {
if low < high {
index := sortKuaisu_getIndex(ary, low, high)
sortKuaisu_sort(ary, low, index-1)
sortKuaisu_sort(ary, index+1, high)
}
}
JavaScript版本
function sortKuaisu(ary) {
sortKuaisu_quick(ary, 0, ary.length - 1)
console.log(ary);
}
// 获取基准数的索引数
function sortKuaisu_getIndex(ary, low, hight) {
let pivot = ary[low] //默认第一位是基准数
let i = low;
let j = hight;
while (i < j) {
//从右往左找一个比基准小的数 (先从右往前找)
while (ary[j] >= pivot && i < j) {
j--;
}
// 从左往右找一个比基准小的数
while (ary[i] <= pivot && i < j) {
i++;
}
// 交换这个两个数据
swap(ary, i, j)
}
// i==j时,交换数,使得排序好的数都分别在基准数两侧
swap(ary, low, i)
return i
}
function swap(ary, l, i) {
let temp = ary[l];
ary[l] = ary[i];
ary[i] = temp;
}
function sortKuaisu_quick(ary, low, hight) {
if (low < hight) {
let index = sortKuaisu_getIndex(ary, low, hight)
sortKuaisu_quick(ary, low, index - 1)
sortKuaisu_quick(ary, index + 1, hight)
}
}