堆排序(Heap_sort)

2024-06-09 22:28
文章标签 heap 堆排序 sort

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

涉及到大根堆的知识点;

最小父节点为length/2-1

父节点的子节点为son = dad*2+1 或  dad*2+2

大根堆即所有父节点大于所有子节点

主要函数:

void Heap_Sort(int *a,int length)
{int i;//从最小的父亲节开始改变,使每一个父亲节点大于儿子节点,从而构成大根堆for(int i = length/2-1;i >=0 ;--i){Heap(a,i,length);}//排序完成后最开始的节点一定是最大的,因为是大根堆swap(a[0],a[length-1]);for(int i = length-1;i > 1;--i){Heap(a,0,i);//因为大根堆父亲节点大于所有子节点,所以排序一次即可swap(a[0],a[i-1]);}
}

先将无序数组转换为大根堆

然后将首节点与最后节点交换,因为大根堆的头节点最大,这时候最末尾元素就是最大的了

然后在用heap一次即可找打剩余最大的数字持续交换直到剩下最后一个元素即可

次要函数:

//使每个父亲节点大于儿子节点
void Heap(int *a,int dad,int length)
{int son = dad*2+1;while(son < length){if(son+1<length && a[son] < a[son+1])//保证儿子节点是两个儿子中最大的{++son;}if(a[dad] < a[son]){swap(a[dad],a[son]);}dad = son;son = dad*2+1;}
}

该函数只能使一个头节点的元素最大,需要从最小的父节点进行循环,因为如果从下往上的话最大的数传播不上去;在主函数后续只需要排序一次是因为:只有头节点不满足大根堆,相当于第一次的最后一步,也就是排序最后一个头节点,因此只需要排序一次即可构成大根堆;

c++代码如下:

#include <bits/stdc++.h>using namespace std;void swap(int &a,int &b)
{int t = a;a = b;b = t;
}//使每个父亲节点大于儿子节点
void Heap(int *a,int dad,int length)
{int son = dad*2+1;while(son < length){if(son+1<length && a[son] < a[son+1])//保证儿子节点是两个儿子中最大的{++son;}if(a[dad] < a[son]){swap(a[dad],a[son]);}dad = son;son = dad*2+1;}
}void Heap_Sort(int *a,int length)
{int i;//从最小的父亲节开始改变,使每一个父亲节点大于儿子节点,从而构成大根堆for(int i = length/2-1;i >=0 ;--i){Heap(a,i,length);}//排序完成后最开始的节点一定是最大的,因为是大根堆swap(a[0],a[length-1]);for(int i = length-1;i > 1;--i){Heap(a,0,i);//因为大根堆父亲节点大于所有子节点,所以排序一次即可swap(a[0],a[i-1]);}
}void print_arr(int *arr,int size)
{for(int i = 0;i < size;++i){cout << arr[i];if(i != size-1){cout << " ";}}
}int main()
{int n;cin >> n;int arr[n];for(int i = 0;i < n;++i){cin >> arr[i];}Heap_Sort(arr,n);print_arr(arr,n);cout << endl;
}

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



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

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

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)

stl的sort和手写快排的运行效率哪个比较高?

STL的sort必然要比你自己写的快排要快,因为你自己手写一个这么复杂的sort,那就太闲了。STL的sort是尽量让复杂度维持在O(N log N)的,因此就有了各种的Hybrid sort algorithm。 题主你提到的先quicksort到一定深度之后就转为heapsort,这种是introsort。 每种STL实现使用的算法各有不同,GNU Standard C++ Lib

优先队列与堆排序

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

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

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

C/C++经典排序问题,sort函数使用

目录 1. 前言 2. 正文 2.1 问题 2.2 解决办法 2.2.1 思路 2.2.2 代码实现 2.2.3 测试结果 3. 备注 1. 前言 大家在学习C语言的时候,是不是经常被排序算法折磨的很难那首,其实都是但是在C++中有专门的,排序函数,而且支持自定义排序算法。下面我就带大家看看,sort函数简单的数组排序中的应用。 2. 正文 2.1 问题 题目描述

堆与堆排序之初见

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

Hive中order by,sort by,distribute by,cluster by的区别

一:order by order by会对输入做全局排序,因此只有一个Reducer(多个Reducer无法保证全局有序),然而只有一个Reducer,会导致当输入规模较大时,消耗较长的计算时间。关于order by的详细介绍请参考这篇文章:Hive Order by操作。 二:sort by sort by不是全局排序,其在数据进入reducer前完成排序,因此,如果用sort

【UVa】10755 Garbage Heap 三维前缀和

题目分析:将前缀和应用到三维,求最大子矩阵。为S[x][y][z]数组中每个坐标保存从(0,0,0)到(x,y,z)范围内的子矩阵的元素和,最后用多次区间加减法可以得到需要的子矩阵的元素和,再用类似一维求最大连续和的方法求三维最大连续和。 代码如下: #include <cstdio>#include <cstring>#include <algorithm>using

list.sort实现根据对象的属性值对集合进行排序

list.sort实现根据对象的属性值对集合进行排序,如下所示List<Map<String,Object>> list = new ArrayList<>();Map<String,Object> map1 = new HashMap<>();map1.put("gz_id",1);map1.put("aaa","aaa");Map<String,Object> map2 = new H