Heap (堆排序)

1.complete binary tree(完全二叉树)
2.parent > children(父节点>子节点)
3.几个完全二叉树的展示:

上述几个二叉树都是完全二叉树。
完全二叉树的特点:生成节点的顺序是从上往下,从左往右。
(思考)上述图怎么添加节点依旧为完全二叉树?
4.heap(堆)的概念

当一个二叉树完全符合,父节点大于子节点时,则可以称为时一个堆。
5.怎么构建一个堆?
实例:

上述图中:4,10,3不满足堆的要求,因此对该这棵树做heapify得到图二;

接着对4,5,1这棵树继续做heapify得到一个完整的堆。

那么如果一个二叉树上所有数字完全打乱排布,怎么构建一个堆呢?

假设该二叉树有n行,则从第n-1行开始,从右往左,从下往上每个节点依次做heapify直至将该二叉树变为完全二叉树,也就是所说的堆。
*6.heapify代码(important)

一个完全二叉树从左往右,从上往下依次标记可以得到如图的,0,1,2,3,4…8,所以可以用一个以为数组表示.
原因:完全二叉树不会有断点,并且用一维数组可以很容易计算出二叉树的父节点和子节点。
(图c1,c2分别表示一个parent的两个子节点,(parent-1)/2永远为整数)
下面上heapify代码:

//堆排序
//heapify函数
#include<stdio.h>
void swap(int arr[],int i,int j)
{int temp;temp = arr[i];arr[i] = arr[j];arr[j] = temp;
}
void heapify(int tree[], int n, int i)
//树用数组表示,n表示树中的节点,i表示对第几个节点做heapify操作。
{int c1 = 2*i + 1;int c2 = 2*i + 2; //依次找到两个子节点 int max = i;if(i > n) //递归出口 当节点大于节点数时直接return{return;} if (c1 < n && tree[c1] > tree[max]){max = c1;} if (c2 < n &&tree[c2] > tree[max]){max = c2;} //在子节点小于总结点时,找出树中最大的节点数 if(max != i){int temp;swap(tree,max,i); //swap函数交换最大的节点数 heapify(tree,n,max); //依次对之后的树做heapify }
}
int main(void){int tree[] = {4,10,3,5,1,2}; //给树排布6个节点 int n = 6;heapify(tree,n,0); //对第0个节点进行heapify操作 int i = 0;for(i=0 ; i<n; i++){printf("%d\n",tree[i]); //之后打印出所有的节点 }return 0;
}

heapify完后应该为:

请自行验证。
7.假如说二叉树上的所有节点数字排布都是乱的那么构建完整的二叉树?

即从左后一个父节点进行heapify操作,依次从下往上,从右往左进行heapify操作即可。
而最后一个父节点可以根据:
Parent = (节点数(n)-1)/2)得到。

//堆排序
//heapify函数
#include<stdio.h>
void swap(int arr[],int i,int j)
{int temp;temp = arr[i];arr[i] = arr[j];arr[j] = temp;
}
void heapify(int tree[], int n, int i)
//树用数组表示,n表示树中的节点,i表示对第几个节点做heapify操作。
{int c1 = 2*i + 1;int c2 = 2*i + 2; //依次找到两个子节点 int max = i;if(i > n){return;} if (c1 < n && tree[c1] > tree[max]){max = c1;} if (c2 < n &&tree[c2] > tree[max]){max = c2;} //在子节点小于总结点时,找出树中最大的节点数 if(max != i){int temp;swap(tree,max,i); //swap函数交换最大的节点数 heapify(tree,n,max); //依次对之后的树做heapify }
}
void build_heap(int tree[], int n) //从最后一个节点依次向上做heapify
{int last_node = n-1;int parent = (last_node-1)/2;int i;for( i =parent; i>=0; i--){heapify(tree,n,i); }
} int main(void){int tree[] = {2,5,3,1,10,4}; //给树排布6个节点 int n = 6;build_heap(tree,n); int i;for(i=0 ; i<n; i++){printf("%d\n",tree[i]); //之后打印出所有的节点 }return 0;
}

Heapify后得到完全二叉树:

8.最激动人心的时刻,有了堆后如何做堆排序?
示例:

交换根节点和最后一个节点,然后砍断最后一个节点:

这样破环了堆,所以在此堆根节点做heapify

继续排序:

继续排序:

9:附上完整代码:

//堆排序
//heapify函数
#include<stdio.h>
void swap(int arr[],int i,int j)
{int temp;temp = arr[i];arr[i] = arr[j];arr[j] = temp;
}
void heapify(int tree[], int n, int i)
//树用数组表示,n表示树中的节点,i表示对第几个节点做heapify操作。
{int c1 = 2*i + 1;int c2 = 2*i + 2; //依次找到两个子节点 int max = i;if(i > n){return;} if (c1 < n && tree[c1] > tree[max]){max = c1;} if (c2 < n &&tree[c2] > tree[max]){max = c2;} //在子节点小于总结点时,找出树中最大的节点数 if(max != i){int temp;swap(tree,max,i); //swap函数交换最大的节点数 heapify(tree,n,max); //依次对之后的树做heapify }
}
void build_heap(int tree[], int n) //从最后一个节点依次向上做heapify
{int last_node = n-1;int parent = (last_node-1)/2;int i;for( i =parent; i>=0; i--){heapify(tree,n,i); }
}
void heap_sort(int tree[] , int n)
{build_heap(tree,n);int i;for(i = n -1;i>=0;i--){swap(tree,i,0);heapify(tree,i,0);//因为不断砍断,所以i可以用来代替节点n依次减一的过程。 }
}
int main(void){int tree[] = {2,5,3,1,10,4}; //给树排布6个节点 int n = 6;heap_sort(tree,n); //改为heap_sort int i;for(i=0 ; i<n; i++){printf("%d\n",tree[i]); //之后打印出所有的节点 }return 0;
}

结果从小到大展示:

该排序学自B站野生技术协会,博主觉得很好做了笔记,希望b站up主的讲解能帮到大家,我的博客也可以让大家最快的来了解到堆排序的简单易懂方法。为什么说易懂,以为博主很笨,看了视频也懂了。hahah

Heap(堆排序)最简单,容易理解的方法相关推荐

  1. 设计模式:简单工厂、工厂方法、抽象工厂之小结与区别

    简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式.其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性. 本文是本人对这三种模式学习后的一个小结以及对他 ...

  2. 如何简单地理解Python中的if __name__ == '__main__'

    如何简单地理解Python中的if __name__ == '__main__' 文章目录: 一.摘要 二. 程序入口 虽然已经知道这个具体的用法,但是这篇文章有很多细节写的还是很好,决定转载一下,日 ...

  3. java接口方法实现_Java接口的简单定义与实现方法示例

    本文实例讲述了Java接口的简单定义与实现方法.分享给大家供大家参考,具体如下: 1.接口是Java中最终要的概念,接口可以理解为一种特殊的类,里面全部是由全局常量和公共的抽象方法所组成. 2.接口的 ...

  4. [C#]简单的理解委托和事件

    委托 在C++中可以利用"函数指针"将对方法的引用作为实参传递给另一个方法,而C#中可以利用委托提供相同的功能. 委托-内部机制 但是委托实际上是一个特殊的类.委托必须直接或间接的 ...

  5. 【设计模式】简单工厂模式+工厂方法模式+抽象工厂模式

    前提导论 故事 不采用工厂模式 简单工厂模式 工厂方法模式 故事 抽象工厂模式 故事结局 前提导论 为了学习设计模式时便于理解,我将用基于农夫和他的村子与森林为背景环境,讲一个故事时,阐述一个设计模式 ...

  6. 基于知识图谱的问答系统简单流程理解(开放型知识图谱、实体类型较多的图谱)

    写在前面 虽然网上代码一大堆,论文一大堆,但是我连一篇实实在在介绍基于知识库的问答系统实现逻辑简单介绍的都找不到. 当然,基于对模板匹配的博客我倒是找到了一篇,见: https://blog.csdn ...

  7. 研磨23种大话设计模式------简单工厂模式 + 工厂方法模式 + 抽象工厂模式

    大家好,我是一位在java学习圈中不愿意透露姓名并苟且偷生的小学员,如果文章有错误之处,还望海涵,欢迎多多指正 如果你从本文 get 到有用的干货知识,请帮忙点个赞呗,据说点赞的都拿到了offer 简 ...

  8. php怎么读取excel里的数据类型,php读取excel表格数据-对PHPExcel一些简单的理解 及怎么读取单元格数据...

    php读取excel,excel下多个个工作表,该怎么读取 php读取excel,excel下多个个工作表的方法: 1.利用PHPExcelReader来完成多个excel的读取. 2.PHPExce ...

  9. Asymmetric Co-Teaching for Unsupervised Cross-Domain Person Re-Identification简单翻译理解

    Asymmetric Co-Teaching for Unsupervised Cross-Domain Person Re-Identification简单翻译理解 Abstract Introdu ...

最新文章

  1. 文本文件如何在其他地方打开
  2. win10显示隐藏文件_如何在Mac上显示隐藏文件?苹果mac显示隐藏文件夹方法
  3. 月亮之上--数学分析版
  4. 『数据库』数据库的查询可不是只知道Select就可以的--关系数据库系统的查询处理
  5. 【蓝桥杯单片机】数码管
  6. Spring4.x()---JdbcDaoSupport的使用
  7. Android源码中的FLAG为何使用16进制
  8. SSM中(Spring-SpringMVC-Mybatis)(二:整合)
  9. ubuntu 的问题,我一个人使用,却显示两人登录?
  10. web.xml的简单解释以及Hello1中web.xml的简单分析
  11. 工序能力指数Cp判定标准(附免费CPK计算工具)
  12. iso镜像添加软件包_ubuntu安装 win7_怎么把自己需要的程序添加到WIN7的原版ISO镜像中? - Win7之家...
  13. 【转载】Linux下用dd命令扇区读写SD卡
  14. 【增长黑客读书笔记-范冰】
  15. 谷歌 Jason Wei | AI 研究的 4 项基本技能
  16. Apple Pay正式入华:能否成支付宝与微信强敌
  17. java什么是布尔型_Java新职篇:是什么是布尔型?
  18. 2019互联网校招薪资表: BAT、华为还没有TMD高
  19. 零基础学C语言设计难吗,【经验分享】零基础想学C语言,过来人提醒大家几点...
  20. ManiSkill 2022机器学习顶会ICLR上的世界顶尖机械臂大赛官网信息整理

热门文章

  1. “敲门砖”简历 巧用思维导图
  2. 计算机专业的求职信英语,计算机专业英语求职信范文
  3. mysql无偿献血_献血的好处1、无偿献血者可以享受免费用血的待遇,献血者本人自...
  4. 销量飞升的零跑汽车,难走进第一梯队
  5. 软文推广要注意这些 效果会更好
  6. 【创建型模式四】建造者模式
  7. 【PTA】2022年蓝桥杯及天梯赛赛前训练(C++练习)
  8. 惠普t630服务器u盘安装系统,t630服务器设置u盘启动
  9. 婚礼MV怎么自己做?制作婚礼MV视频的方法,小白也能3步搞定
  10. java失物招领及估价拍卖系统