当前位置:网站首页>堆排序 O(nlogn) ----选择排序
堆排序 O(nlogn) ----选择排序
2022-08-11 11:51:00 【Bruce1801】
文章目录
一、完全二叉树
完全二叉树是一种特殊的二叉树。从上大下,从左到右,每一层的结点都是满的,最下边一层所有的节点都是连续集中在最左边。
二、堆
堆排序分为两种,分别是大顶堆和小顶堆
- 大顶堆:在完全二叉树的基础上,每个节点的值都大于或等于其左右孩子节点
- 小顶堆:在完全二叉树的基础上,每个节点的值都小于或等于其左右孩子节点的值
三、堆排序的特点
堆排序是利用堆这种数据结构而设立的一种排序算法
构建完全二叉树
基本思想
- 将待排序的序列构造成一个大顶堆,根据大顶堆的性质,当前堆的根节点就是序列中的最大的元素
- 将堆顶元素和最后一个元素交换,然后剩下的节点重新构造成一个大顶堆;
- 重复步骤2,如此反复,从第一次构建大顶堆开始,每一次构建,我们都能获得一个序列的最大值,然后把它放到大顶堆的尾部。最后,就得到一个有序的序列了
图示
第一步:构建大顶堆(这里我们都是以最后一个开始讲解,不在是中间位置,讲解游标i的时候需要带上i的下边是一个大顶堆)
- :初始化状态,右下角为下标
- : index = 5开始,发现它没有兄弟节点,并且父节点小于它,父节点的计算放方式为:
index = [arr.length - 1] /2 - :接下来index减1,那么index节点变为4,这时候他要和兄弟节点进行对比,发现它比兄弟节和父节点都大
那么他就和父节点机型交换。 - :接下来index减2,他有和兄弟节点进行对比,发现它比兄弟节点大,还比父节点大,那么它和父节点进行交换
- :交换完成之后,发现2号节点不再大于其子节点了,所有需要在交换一次
//选取孩子结点的左孩子结点,继续向下筛选
parent = lChild;
lChild = 2 * lChild + 1;
- :检查一下,已将满足最大的条件了,大顶堆已经构建完成
第二步:将堆顶元素和最后一个元素交换,然后将剩下的节点重新构造成一个大顶堆
:0号节点是最大值,我们将它与最后一个节点交换位置
:此时的堆不是大顶堆需要重现构建
:再次调整,index = 1 ,此时 下标为1的值为5,值大于左右子树,所以 index -1 ,此时值为1.然后需要进行交换
交换完成之后,发现1号节点不再大于其子节点了,所有需要在交换一次:交换后的结果是
:0号节点是最大值,我们将它与最后一个节点交换位置
:此时的堆不是大顶堆需要重现构建,此时 index = 1,1号位置大于其孩子节点的值,所以 index -1 ,此时index = 0
0号位置小于其左子树。所以进行交换:交换后的结果是
:0号节点是最大值,我们将它与最后一个节点交换位置
:此时的堆不是大顶堆需要重现构建,此时 index = 0,0号位置小于其孩子节点的值,左右子树进行计较之后发现右子树更大,所以和右子树进行交换。
:交换后的结果是
;0号节点是最大值,我们将它与最后一个节点交换位置
:此时的堆不是大顶堆需要重现构建,此时 index = 0,0号位置小于其孩子节点的值,左右子树进行计较之后发现做子树更大,所以和右子树进行交换。
:交换后的结果是
;0号节点是最大值,我们将它与最后一个节点交换位置
最终我们就能得到最后的答案
代码
public class HeapSort {
public static void main(String[] args) {
int[] arr = new int[]{
587,956,12,47,30,20,15,11,21,31,57,91,35,120};
for (int p = arr.length-1;p>=0;p--){
sort(arr,p,arr.length);
}
for(int i = arr.length-1; i>0;i--){
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
sort(arr,0,i);
}
System.out.println(Arrays.toString(arr));
}
/** * 构建大顶堆的逻辑 * @param arr * @param parent * @param length */
public static void sort(int[] arr,int parent,int length){
int Child = 2 * parent +1; //左孩子
while(Child < length){
// 判断有没有右孩子,以及右和左孩子谁大
int rChild = Child+1;
if(rChild < length && arr[rChild] > arr[Child]){
Child ++;
}
// 父子节点进行对比
if(arr[parent] < arr[Child]){
int temp = arr[parent] ;
arr[parent]= arr[Child];
arr[Child] = temp;
parent = Child;
Child = 2 * Child +1;
}else{
break;
}
}
}
}
边栏推荐
猜你喜欢
Network Security - nmap
VirtualLab: Ince - array of laser Gaussian beam generated vortex observation
黑海港口外运农产品问题联合协调中心:正努力加速粮食外运
图像识别(八)| 还对全连接层迷迷糊糊?背会一首诗就行了
From Douyin to Volcano Engine——Seeing the Evolution and Opportunities of Streaming Media Technology
在华门店数超星巴克,瑞幸咖啡完成“逆袭”?
Jmeter性能测试
重要消息丨.NET Core 3.1 将于今年12月13日结束支持
五分钟教你内网穿透
VirtualLab:Ince-Gaussian光束产生涡旋阵列激光束的观测
随机推荐
WPF 实现内阴影
98转出0转入,985高校土木工程沦为“天坑”引热议
HM升压IC芯片代理商
error: ‘const char* libc_name_p(const char*, unsigned int)’ redeclared inline with ‘gnu_inline’ attr
困扰所有SAP顾问多年的问题终于解决了
【剑指offer-牛客网刷题】第一篇-斐波拉契数列-C实现
开源H.264 Video Encoder IP Core V2.0 介绍
在华门店数超星巴克,瑞幸咖啡完成“逆袭”?
谷歌搜索,全球宕机??
FS2956A 输入8-120V 用于液晶仪表5V-USB 充电口方案
Flutter 教程之 在 Flutter 中生成 JSON 模型,在 Flutter GetX 中过滤列表和延迟搜索
从抖音到火山引擎——看流媒体技术演进和机会
SH7001单电池恒压线性充电IC
[10 o'clock open class]: Optimization of AV1 encoder and its application in streaming media and real-time communication
【医学统计学】二项分布
pip安装后仍有ImportError No module named XX问题解决
KMP与AC自动机详细讲解(带图)
2021年全国大学生电子设计竞赛官方通知正式发布
d共享左值
OpenHarmony如何选择图片在Image组件上显示(eTS)