堆排序(大顶堆)

2023-12-16 17:08
文章标签 堆排序 大顶

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

一:堆
堆可以看做一个完全二叉树,同时该完全二叉树满足双亲结点大于等于孩子结点(大顶堆),或者双亲结点小于等于孩子结点(小顶堆)。
二:堆排序(以大顶堆为例)
大顶堆产生顺序序列,小顶堆产生逆序序列。
已知序列[a0,a1,…,an]。测试序列为{5,9,3,7,6,5};
这里写图片描述
a)将序列初始化,从最后面的非叶子结点开始调整产生大顶堆。
这里写图片描述
b)将a0和an交换,a0到an-1(无序区)不满足大顶堆则重新调整,an为有序区。(a0处保存的是无序区生成的子堆中的最大值。)
这里写图片描述
c)进行n-1次(b)步的调整,有序区将包含n-1个有序元素,最后一个元素即为最小元素。排序完成。
这里写图片描述

#include<iostream>
using namespace std;void swap(int *a, int *b)
{int temp = *a;*a = *b;*b = temp;
}void HeadAdjust(int a[], int i, int length)
{int lChild = 2*i+1;int rChild = 2*i+2;int max = i;if(i<=(length-1)/2){if(lChild<=length-1 && a[lChild]>a[max]){max = lChild;}if(rChild<=length-1 && a[rChild]>a[max]){max = rChild;}if(max != i){swap(&a[max],&a[i]);HeadAdjust(a,max,length);}}
}void InitHead(int a[], int length)
{for(int i=(length-1)/2;i>=0;i--){HeadAdjust(a,i,length);}
}void HeadSort(int a[], int length)
{InitHead(a,length);
//  for(int i=0; i<length; i++)
//  {
//      cout<<a[i]<<" ";
//  } 
//  cout<<endl;for(int i=length-1;i>0;i--){swap(&a[0],&a[i]);HeadAdjust(a,0,i);
//      for(int i=0; i<length; i++)
//      {
//          cout<<a[i]<<" ";
//      } 
//      cout<<endl;} 
}
int main()
{int a[100] = {0};int length=0;cin>>length;if(length>0){for(int i=0; i<length; i++){cin>>a[i];}HeadSort(a,length);for(int i=0; i<length; i++){cout<<a[i]<<" ";}cout<<endl;}return 0;
} 

运行结果:
这里写图片描述

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



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

相关文章

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() {

堆排序的例题

答案:D C 知识点: 堆排序是把数组排成大顶堆或者小顶堆,选择根结点的最大值或者最小值,因此它是选择排序的方法 堆排序的方法是: 先把数组所有数据组成一个二叉树,然后调整结点与左右孩子树之间的位置,使之成为大顶堆或小顶堆。构建大顶堆或者小顶堆的过程时间算法是O(logn) 由于要进行(n-1)次比较,因此整体算法复杂度是O(nlogn) 需要中间更换位置的需要一个空间存储中间值,