《算法导论》@读书笔记@ 第六章 - 堆排序(包含js版代码实现)

什么是堆排序

堆(英语:heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。


在javascript中我们用数组来实现这一种数据结构
堆排序就是利用这种数据结构进行排序

算法思路

就是建立一个最大堆,然后利用堆顶永远是最大数值来排序
如下图所示,每次都将黄色区域的值(堆顶)与粉红区域的值(末位)进行交换

然后排除末位 在剩下的数组中进行最大堆重塑
如此往复,到这个堆只剩下一个元素 就完成了整个排序过程

算法过程

  1. 首先定义一个排序方法 HeapSort
  2. 然后我们需要建立一个最大堆BuildMaxHeap
  3. 然后我们需要一个维护堆的性质的方法,也就是重塑堆得方法MaxHeap
  4. 往复的从堆顶与数组末位互换位置 然后重塑

BuildMaxHeap的前提是我们要先把数组看成一个堆,看成堆了之后我们要知道数组中的位置和堆的位置的对照关系,如下图所示

我们以堆底开始利用MaxHeap构建最大堆
MaxHeap是假设存在一个堆,它的堆顶的左节点和右节点都是符合最大堆的性质的

算法实现

/**
 * 时间复杂度 平均:O(nlog2n)。
 * 空间复杂度:O(1)。
 * 稳定性:不稳定
 */

function HeapSort(arr) {
    
    
	var len = arr.length;
	BuildMaxHeap(arr,len);
	for (var i = len-1 ; i > 0; i--) {
    
    
		let box = arr[0];
		arr[0] = arr[i];
		arr[i] = box;
		MaxHeap(arr,0,i);
	}
	return arr
}

function MaxHeap(arr,i,length) {
    
    
	var largest = null;
	var node = arr[i]; //保存当前节点
	var left = i * 2 + 1 ; //定位节点左
	var right = i * 2 + 2; //定位节点右	
	//判断当前有这个节点 (这里会存在当前这个的子节点不存在的情况)处理一下边界情况
	if (left < length && node < arr[left]) {
    
    
		largest = left
	}else{
    
    
		largest = i;
	}
	if (right < length && arr[largest] < arr[right]) {
    
    
		largest = right
	}
	//如果不是i是最大节点 以node作为辅助节点 交换位置
	if (largest != i) {
    
    
		arr[i] = arr[largest];
		arr[largest] = node;
		MaxHeap(arr,largest,length);
	}
}
//建立一个最大堆
function BuildMaxHeap(arr,len){
    
    
	if(len%2!=0){
    
    
		len = len +1 ;
	}
	for(let i = len/2;i>=0;i--){
    
    
		MaxHeap(arr,i,len)
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_38616850/article/details/110877410
今日推荐