堆排序 实现和特点
(普通)
特点:
堆排序是基于二叉树所形成的一棵具有稳定结构的完全二叉树,稳定是当前节点与子节点之间有特定的排序准则,以致于整棵树都是按照此规则进行的,所以整棵树是具有稳定结构的。
定义:
一棵完全二叉树可以由数组进行表示,而数组具有以下特点;
- 如果一个节点在数组中的index 为 i 那么
他的父节点坐标 = i/2-1
他的左子节点 2i+1
他的右子节点 2i+2
节点数 等于 数组长度
- 方法
Heapify
定义:进行当前节点与2个子节点之间的比较,形成一个稳定的二叉树,将比较最大的节点与当前节点对换,并且交换之后的节点递归进行 heapify
实现:
// 稳定结构下进行 heapify
const heapify = (tree, n, i) => {
if (i >= n) {
return
}
let max = i;
let c1 = i * 2 + 1;
let c2 = i * 2 + 2
if (c1 < n && tree[c1] > tree[max]) {
max = c1
}
if (c2 < n && tree[c2] > tree[max]) {
max = c2
}
if (max != i) {
swap(tree, max, i)
heapify(tree, n, max)
}
}
const swap = (tree, l, r) => {
let tmp = tree[l]
tree[l] = tree[r]
tree[r] = tmp
}
const main = () => {
let tree = [4, 10, 3, 5, 1, 2]
heapify(tree, tree.length, 0)
console.log(tree)
}
main()
- 不稳定结构下进行稳定重构堆排序
定义:需要对整个树进行heapify排序,一般是从树高-1(倒数第二层)开始进行排序,一直排序到顶点节点就完成了整棵树的排序;
实现:
const heapify = (tree, n, i) => {
if (i >= n) {
return
}
let max = i;
let c1 = i * 2 + 1;
let c2 = i * 2 + 2
if (c1 < n && tree[c1] > tree[max]) {
max = c1
}
if (c2 < n && tree[c2] > tree[max]) {
max = c2
}
if (max != i) {
swap(tree, max, i)
heapify(tree, n, max)
}
}
const swap = (tree, l, r) => {
let tmp = tree[l]
tree[l] = tree[r]
tree[r] = tmp
}
const main = () => {
let tree = [4, 1, 3, 2, 10, 5]
// 找到最后一个节点的父节点,并从此开始向上排序
let p = (Math.round((tree.length - 1) / 2)) - 1
debugger
for (let i = p; i >= 0; i--) {
heapify(tree, tree.length, i)
}
console.log(tree)
}
main()
sort 排序 ,从小到大进行排序
定义:每次将顶点和数组中最后一个位置值对换,并且淘汰最后一个值放入数组,依次执行下来得到的序列就是从小到大排序了;
实现:
const heapify = (tree, n, i) => {
if (i >= n) {
return
}
let max = i;
let c1 = i * 2 + 1;
let c2 = i * 2 + 2
if (c1 < n && tree[c1] > tree[max]) {
max = c1
}
if (c2 < n && tree[c2] > tree[max]) {
max = c2
}
if (max != i) {
swap(tree, max, i)
heapify(tree, n, max)
}
}
const swap = (tree, l, r) => {
let tmp = tree[l]
tree[l] = tree[r]
tree[r] = tmp
}
const heapBuild = (tree) => {
// 找到最后一个节点的父节点,并从此开始向上排序
let p = (Math.round((tree.length - 1) / 2)) - 1
for (let i = p; i >= 0; i--) {
heapify(tree, tree.length, i)
}
}
const main = () => {
let tree = [4, 1, 3, 2, 10, 5]
heapBuild(tree)
console.log(tree)
for (let i = tree.length - 1; i >= 0; i--) {
swap(tree, i, 0)
heapify(tree, i, 0)
}
console.log(tree)
}
main()