堆排序;大顶堆、小顶堆

2023-10-21 16:28
文章标签 堆排序 大顶 小顶

本文主要是介绍堆排序;大顶堆、小顶堆,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

堆排序

基本介绍

堆排序基本思想

堆排序步骤图解

在第二个步骤中,将节点6和它的两个左右节点比较大小,发现右节点最大,所以将节点6和节点9进行交换,如图所示,数组相应位置的值也交换

总结

代码实现

""" 堆排序 """
class HeapSort:def __init__(self, arr):self.arr = arrdef adjust_heap(self, i: int, n: int):"""arr[i] 对应一个非叶子节点,adjust_heap()方法的作用就是将arr[i]这个非叶子节点下的所有子树构建成大顶堆即从该非叶子节点开始,它下面的子树都满足大顶堆的定义如图中的第一个非叶子节点arr[1] = 6,其对应的子树如下,构建之后变为如下6                       9=>5       9               5       6arr=[4,6,8,5,9], i=1 => adjust_heap() => 构建之后得到arr=[4,9,8,5,6]下一次再调用adjust_heap():arr=[4,9,8,5,6], i=0 => adjust_heap() => 构建之后得到arr=[9,6,8,5,4]adjust_heap()是将非叶子节点对应的:param i: 表示非叶子节点在数组中的索引:param n: 表示构建大顶堆时的元素个数(即要对多少个元素进行构建大顶堆),m是逐渐减少的:return:"""temp = self.arr[i]  # 保存非叶子节点的值k = 2 * i + 1  # k 为叶子结点的左子节点while k < n:# k + 1 = 2 * i + 1 + 1 = 2 * i + 2,即表示右子节点# self.arr[k]表示左子节点的值,self.arr[k+1]表示右子节点的值if k + 1 < n and self.arr[k] < self.arr[k + 1]:# 如果左子节点小于右子节点的值,让 k 指向右子节点k += 1  # => k = 2 * i + 2if self.arr[k] > temp:  # 如果子节点(左/右子节点)大于父节点(非叶子结点)self.arr[i] = self.arr[k]  # 把较大的值赋值给当前节点i = k  # 让 i 指向 k 的位置else:breakk = k * 2 + 1  # 下一个左子节点,即左子节点的左子节点# 当循环结束后,已经在局部将以 i 为父节点的树的最大值放在了堆顶self.arr[i] = temp  # 将 temp 值放到调整后的位置"""以上代码请结合图来理解!!!"""def heap_sort(self):"""讲一个数组(该数组是二叉树顺序存储之后的数组)构建为大顶堆:return:"""print("=======堆排序=======")print("排序前的数组:", self.arr)# self.adjust_heap(1, len(self.arr))# print("第一次调整后的数组:", self.arr)  # [4, 9, 8, 5, 6]# self.adjust_heap(0, len(self.arr))# print("第二次调整后的数组:", self.arr)  # [9, 6, 8, 5, 4]n = len(self.arr)# 将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆i = n // 2 - 1  # 从第一个非叶子节点开始进行调整,即从左往右,从下往上进行while i >= 0:self.adjust_heap(i, n)i -= 1# 将堆顶元素与数组末尾元素交换,将最大元素“沉”到数组末尾# 重新调整堆结构,使其满足大顶堆或小顶堆的定义,然后继续交换堆顶元素与数组末尾元素# 反复执行直到整个序列有序j = n - 1while j > 0:# self.arr[0]为堆顶元素,self.arr[j]为数组末尾元素,将其交换temp = self.arr[j]self.arr[j] = self.arr[0]self.arr[0] = temp# 交换后重新调整堆结构,0表示从根节点开始,将整棵树进行调整self.adjust_heap(0, j)j -= 1print("排序后的数组:", self.arr)heap_sort = HeapSort([4, 6, 8, 5, 9])
heap_sort.heap_sort()

这篇关于堆排序;大顶堆、小顶堆的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/255564

相关文章

在Java中实现堆排序的步骤详解

《在Java中实现堆排序的步骤详解》堆排序是一种基于堆数据结构的排序算法,堆是一种特殊的完全二叉树,堆排序利用堆的性质通过一系列操作将数组元素按升序或降序排列,本文给大家介绍了如何在Java中实现堆排... 目录引言一、堆排序的基本原理二、堆排序的实现步骤三、堆排序的时间复杂度和空间复杂度四、堆排序的工作流

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

优先队列与堆排序

PriorityQueue 优先级队列中的元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索。无论何时调用remove方法,总会获得当前优先级队列中的最小元素(其实是返回堆顶元素),但并不是对所有元素都排序。它是采用了堆(一个可以自我调整的二叉树),执行增加删除操作后,可以让最小元素移动到根。 堆排序复习 package com.jefflee;import java.util.Arr

6.2排序——选择排序与堆排序

本篇博客梳理选择排序,包括直接选择排序与堆排序 排序全部默认排成升序 一、直接选择排序 1.算法思想 每次遍历都选出最小的和最大的,放到序列最前面/最后面 2.具体操作 (1)单趟 每次遍历都选出最小的和最大的。遍历时,遇到更小的,更新min,遇到更大的,更新max (2)单趟变整体 每趟遍历完之后,begin++,end– 程序结构如下 while(begin<end){//

堆与堆排序之初见

堆(本文只提二叉堆,当然也有多叉堆)作为一种数据结构,是一个数组,可以被看成是一个近似的完全二叉树,树上的每一个节点对应数组中的一个元素,并且除了最底层节点外,该树是完全充满的,而且是从左向右依次填充。 我们目前经常听到的名词“堆”已经被引申为“垃圾收集存储机制”,但本文提及的“堆”指的是堆数据结构。 为了后续描述方便,我们定义堆的数组为H,用H.length表示堆数组的大小,用H.size表示堆

堆排序算法剖析(基于Java)

什么是堆结构? 堆排序的关键是构造堆结构,首先谈一下堆结构的定义,堆结构是一种树结构,准确地说是一个完全二叉树,完全二叉树的定义在这里就不多赘述了,百度知道。 按照排序顺序,堆结构可以分为两种: 1.按照从小到大的顺序排序,要求非叶节点的数据要大于或等于其左、右子节点的数据。 2.按照从大到小的顺序排序,要求非叶节点的数据要小于或等于其左、右子节点的数据。 本文以从小到大的顺序为例进行介

排序算法(动图详细讲解)(直接插入排序,希尔排序,堆排序,冒泡排序)

前言:         排序的方式有很多种,不同的排序思想是不一样的。         但是排序的时间复杂度和空间复杂度也都有区别。         例如:         最简单的冒泡排序,时间复杂度为O(N)         对排序的时间复杂度为O(N*logN)。 接下来就来仔细分析每种排序的思路,并写出代码。 插入排序:  基本思想:         直接插入排序是一种简

堆的建立、插入、出堆、堆化、topk问题、堆排序(C语言实现)

堆的建立、插入、出堆、堆化、topk问题、堆排序 使用数组来存储堆 堆顶为序号0,堆底为序号 size - 1 假设树为完全二叉树,当前节点和双亲节点的关系可以通过公式表达 // 小顶堆: 对 heaptifyUp 和 heaptifyDown 函数的逻辑进行一些调整。void initHeap(float **arr, int *size) { *arr = (float *)malloc

内部排序之三:堆排序

前言    堆排序、快速排序、归并排序(下篇会写这两种排序算法)的平均时间复杂度都为O(n*logn)。要弄清楚堆排序,就要先了解下二叉堆这种数据结构。本文不打算完全讲述二叉堆的所有操作,而是着重讲述堆排序中要用到的操作。比如我们建堆的时候可以采用堆的插入操作(将元素插入到适当的位置,使新的序列仍符合堆的定义)将元素一个一个地插入到堆中,但其实我们完全没必要这么做,我们有执行操作更少的方法,

算法-排序算法:堆排序(HeapSort )【O(nlogn)】

MyArray.java /*** 数组** @author* @version 2018/8/4*/public class MyArray<E> {private E[] arr;private int size;public MyArray(int capacity){arr = (E[])new Object[capacity];size = 0;}public MyArray() {