- 快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
首先设定一个分界值,通过该分界值将数组分成左右两部分。
将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都 小于分界值,而右边部分中各元素都大于或等于分界值。
然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
/**
* 快速排序
* @param {array} - arr 需要排序的数组
* @returns {array}
*/
export function quickSort(arr: number[]) {
quick(arr, 0, arr.length - 1) // 数组从0 - 结束 有序
return arr
}
function quick(arr: number[],left:number, right:number) {
// 数组长度大于1才排序,1个数字不需要排序
if (arr.length > 1) {
let index = partition(arr, left, right)
if (left < index - 1) { // 左边 继续 做有序操作,直到递归到最后
quick(arr, left, index - 1)
}
if (index < right) { // 右边 继续 做有序操作,直到递归到最后
quick(arr, index, right)
}
}
}
function partition(arr: number[],left:number,right:number) {
// 将数组以pivot 为标准 划分为俩半 局部有序
let pivot = arr[Math.floor(left + right)/2]
let i = left
let j = right
while(i <= j) {
while (arr[i] < pivot) {
i++
}
while (arr[j] > pivot){
j--
}
if (i <= j) {
swap(arr, i, j)
i++
j--
}
}
return i // 到最后 i == j 就是pivot的下标
}
/***
这种实现思路 是利用 i j 两个指针 , 将 数组 以 pivot(枢纽) 分割成两半
左边 小于 pivot 右边大于pivot ,然后递归 分而治之 .
例如 数组 [ 3 , 6 , 5 , 7 , 4 , 1 , 8 , 2 , 9]
选取pivot : 4 , left : 3 right : 9
//left 会一直找到 >= 4 时停住
//right 会一直找到<= 4 停住
=> left =>6 , right => 2 这个时候 swap
[3,2,5,7,4,1,8,6,9] 继续循环
=>left =>5 , right =>1 调用 swap
[ 3,2,1,7,4,5,8,6,9]
=>left => 7 , right =>4 调用 swap
[3,2,1,4,7,5,8,6,9] 退出循环 ( i > j )
你会发现 在 4 的左边 都比 4 小
在 4 的右边都比 4 大 ,这个时候以4 为枢纽分开 递归即可
***/
-
堆排序
-
堆的概念
堆是一颗顺序存储的二叉树
大根堆:其中每个节点的值都不小于其子节点
小根堆:其中每个节点的值都不大于其子节点
-
堆排序的过程
创建堆 => 调整堆 => 选取最值 => 再次调整堆
-
代码实现
function swap(arr, i, j){ let temp = arr[i] arr[i] = arr[j] arr[j] = temp } function BuildHeap(arr){ let len = arr.length // 因为二叉树的特点, 父节点 i 左子节点 2i+1 右子节点 2i+2 let start = Math.floor(len/2) - 1 for(let i = start; i >= 0; i--){ heapify(arr, i, len) } } function heapify(arr, i, end){ let current = i // 父节点 i 左子节点 2i+1 右子节点 2i+2 // 0 // 1 2 // 3 4 5 6 let left = 2*i + 1 let right = 2*i + 2 if(left < end && arr[current] < arr[left]){ current = left } if(right < end && arr[current] < arr[right]){ current = right } if(current != i){ swap(arr, i, current) heapify(arr, current, end) } } function HeapSort(arr){ let len = arr.length - 1 // 1.创建堆 BuildHeap(arr) for(let i = len; i > 0; i--){ swap(arr, 0, i) heapify(arr, 0, i) } return arr }
-