首页 > 其他分享 >堆排序

堆排序

时间:2024-09-03 19:13:50浏览次数:4  
标签:arr leftIndex 元素 堆排序 let largestIndex 节点

定义

堆是一棵完全二叉树。分为大顶堆和小顶堆
大顶推:所有节点都大于等于它的两个子节点
小顶堆:所有节点都小于等于它的两个子节点

伪代码

推排序步骤,以升序排列为例,用大顶堆。(降序排列,用小顶堆)

  1. 构建大顶推
  2. 把堆顶元素和堆尾元素交换,此时堆尾元素是最大的,堆的大小减一
  3. 堆顶元素下沉到指定位置
  4. 重复2-3步,直到堆的大小为1

关键在于如何构建一个大顶堆(对节点进行下沉):
从最后一个非叶子节点开始;
逐个检查每个节点,如果一个节点的值小于其子节点的值,我们就将它与较大的子节点交换位置;
交换后,这个交换后的节点可能导致不满足堆的特性,因此还需要继续下沉(Heapify)

举个例子

需要注意的是:对于一个完全二叉树
它的最后一个非叶节点下标是 Math.floor(len/2) - 1,len是二叉树的节点个数
下标为i的节点,它的左子节点是2*i+1, 右子节点是2*i+2

比如说对于[5,2,7,3,6,1,4]
最后一个非叶子节点下标是Math.floor(len/2) - 1=2, 也就是说最后一个非叶子节点是7, 构建最大堆的过程如下:

时间复杂度

O(nlogn)

实现

function heapSort(arr) {
	// 构建最大堆
	let n = arr.length;
	for(let i = Math.floor(n/2 - 1); i>=0;i--) {
		heapify(arr, n, i) // 把下标为i的节点放到合适的位置上
	}

	while(n>1) {
		// 交换堆顶元素和堆尾元素
		[arr[0], arr[n-1]] = [arr[n-1], arr[0]]
		// 堆的个数减一
		n--
        // 把堆顶元素放到合适的位置
		heapify(arr, n, 0)
	}
}

function heapify(arr, n, i) {
	let largestIndex = i
	let leftIndex = 2 * i + 1
	let rightIndex = 2 * i + 2

	if(leftIndex < n && arr[leftIndex] > arr[largestIndex]) {
		largestIndex = leftIndex
	}
	if(rightIndex < n && arr[rightIndex] > arr[largestIndex]) {
        largestIndex = rightIndex
    }
    if(largestIndex!==i) {
	    [arr[i], arr[largestIndex]] = [arr[largestIndex], arr[i]]
	    heapify(arr, n, largestIndex)
    }
}

标签:arr,leftIndex,元素,堆排序,let,largestIndex,节点
From: https://www.cnblogs.com/duanlvxin/p/18395230

相关文章

  • 堆排序python实现
    一,树与二叉树1,树        树是一种数据结构,比如目录结构。        树是由n各节点组成的集合:    1.如果n=0,那存在一个节点作为数的根节点,其他节点可以分为m个集合,每个集合本身又是一颗树,比如:树的相关概念,比如根节点,叶子节点什么的不做过多介绍......
  • 【数据结构】二叉树的顺序结构,详细介绍堆以及堆的实现,堆排序
    目录1.二叉树的顺序结构2.堆的概念及结构3.堆的实现3.1堆的结构3.2堆的初始化3.3堆的插入 3.4堆的删除3.5获取堆顶数据3.6堆的判空3.7堆的数据个数3.8堆的销毁4.堆的应用4.1堆排序4.1.1向下调整建堆的时间复杂度 4.1.2向上调整建堆的时间复杂......
  • 堆排序算法及优化(java)
    目录1.1引言1.2堆排序的历史1.3堆排序的基本原理1.3.1堆的概念1.3.2堆排序的过程1.3.3堆调整1.3.4堆排序算法流程1.4堆排序的Java实现1.4.1简单实现1.4.2代码解释1.4.3优化实现1.4.4代码解释1.5堆排序的时间复杂度1.5.1分析1.5.2证明1.6堆排序......
  • 大根堆排序
    原理假设待排序目标为数组arr,可将其视为一个完全二叉树。在大根堆排序中,根节点为最大值,我们循环将根取出,并减少大根堆的长度和调整堆使之堆维持大根堆,直至取出堆中全部节点数据。因为我们每次都是取出大根堆的最大值,故取出数据便有序了。完全二叉树父节点和叶子节点的索引关......
  • 堆排序的插入和删除
    插入:    1. 检查你的顺序表是否还有位置去插入,如果没有需要扩展    2.插入到已有序列的后一位置    3.和其父节点进行比较,是否满足大根堆/小根堆规则    4.不满足则需要交换数值删除:    1.将最后一个元素覆盖将要删除的元......
  • 详解堆排序(内附代码实现)
    堆排序有两个过程下标为i的节点的父节点下标:(i-1)/2整除下标为i的节点的左孩子下标:i*2+1下标为i的节点的右孩子下标:i*2+2待排序序列为:​ 23814910716141.建大顶堆​ 首先建立无序堆 然后建立大顶堆:从右往左,从下往上,递归的选择子节点最大的往上浮首先14大......
  • 蒜法笔记(Java)- 堆排序
    逻辑    堆是一种所有父节点都大于等于(大根堆)或小于等于(小根堆)其子节点的完全二叉树。堆排序(升序)就是一种将数组视为一个完全二叉树,将其变为一个大根堆后将堆顶放到数组尾,重复n次后数组有序的排列方法,时间复杂度为O(nlogn)。(感觉好像冒泡哦)    简述:将数组视......
  • C语言实现排序之堆排序算法
    一、堆排序算法基本思想堆排序是一种比较有效的排序方法,其基本思想是:构建最大堆:首先将待排序的数组构建成一个最大堆,即对于每个非叶子节点,它的值都大于或等于其子节点的值。排序:然后将堆顶元素(最大值)与堆的最后一个元素交换位置,将其移出堆,并调整剩余元素以保持最大堆的性质......
  • 堆排序以及向上、向下调整算法的时间复杂度推导及实现(超详细)
    什么是堆排序?堆排序是由堆这种数据结构所设计的一种排序算法堆的分类:大根堆:每个父结点的值都大于子结点小根堆 :每个父结点的值都小于子结点 在了解完堆之后,需要先了解建堆,建堆有向上建堆建大堆或者小堆,也有向下建堆建大堆或者小堆 建大堆还是小堆看子结点和父结点的......
  • 排序算法 堆排序 HeapSort -- C语言实现
    堆排序堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:大顶堆:每个节点的值都大于或等于其子......