算法三:树和堆排序
来源:互联网 发布:求欧美复古风淘宝店铺 编辑:程序博客网 时间:2024/06/16 17:05
1、树(不包含回路的,即n个结点恰好有n-1条边)
任意两个结点有且仅有唯一的一条路径连通。
根/祖先/根节点(没有父亲)
节点/结点
夫节点/父亲
子节点/儿子
叶结点(没有儿子)
深度:根到这个结点的层数。
2、二叉树:每个结点最多有两个儿子(左儿子,右儿子)
满二叉树:每个结点都有两个儿子/所有的叶结点都有相同的深度。
深度为h且有2^h-1个结点的二叉树。
完全二叉树:满二叉树最右边位置上拿掉一个或者几个叶结点
深度为h,除h层外,其他各层(1 - h-1)的结点数都达到最大个数。
完全二叉树存储:一维数组,从左到右一层一层放。
有N个结点,那么这个完全二叉树的高度为log2 N。
最典型的应用就是堆。
3、最小堆:所有父结点都比子结点要小
随便n元素的数,按照完全二叉树方式放入一个数组,生成最小堆:
1、从最后一个非叶结点(结点数组编号为n/2)开始,对该结点和下面的左右叶结点进行比较,使最小的数放在非叶结点上。
2、扫描完这层后,开始扫描上一层,该结点如果要移位,就需要对下面及下面的叶结点进行比较,使其符合最小堆要求,不移位不比较。
3、重复,直到扫描到根节点(结点编号为1)为止。
时间复杂度O(N)
5、堆排序
时间复杂度和快速排序一样O(NlogN)。
以从小到大排序为例。
1、生成最大堆
2、把数组中最后h[n]的数和h[1]的数进行交换,n--
3、补上来的数h[1]和子节点一层一层对比,把小的数往上移,直到不能移动时,再跳到2反复。
create();
while(n>1)
{
swap(1,n);
n--;
siftdown(1);
}
siftdown(int i)
{
while(!到底或已经没有小的)
{
n[i]和左儿子比,和右儿子比,如果有小的交换并记录在t中。
更新到交换后的结点i=t。
}
}
6、堆的应用
优先队列:普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。
二叉堆就是优先队列(父节点大于子节点)
求一个数列中第K大/小的数。
取出K个数建一个大小为K的最小/大堆,再从K+1个数开始,依次拿去和堆顶比较,如果要小/大,就舍弃,如果大/小就一层一层往下比和移。
时间复杂度O(NlogN)
并查集/不相交集数据结构的算法:
通过一个数组来实现,其本质是维护一个森林,刚开始的时候,森林的每个点都是孤立的,可理解成一个结点的树,
之后通过一些条件,逐步将这些树合并成一棵大树。判断两个节点是否已经在同一棵树(数其实是个集合)中的时候,
也要注意必须求其根源,中间父亲节点是不能说明问题的,必须找到其祖宗判断两个结点的祖宗是否是同一个根结点才行。
任意两个结点有且仅有唯一的一条路径连通。
根/祖先/根节点(没有父亲)
节点/结点
夫节点/父亲
子节点/儿子
叶结点(没有儿子)
深度:根到这个结点的层数。
2、二叉树:每个结点最多有两个儿子(左儿子,右儿子)
满二叉树:每个结点都有两个儿子/所有的叶结点都有相同的深度。
深度为h且有2^h-1个结点的二叉树。
完全二叉树:满二叉树最右边位置上拿掉一个或者几个叶结点
深度为h,除h层外,其他各层(1 - h-1)的结点数都达到最大个数。
完全二叉树存储:一维数组,从左到右一层一层放。
有N个结点,那么这个完全二叉树的高度为log2 N。
最典型的应用就是堆。
3、最小堆:所有父结点都比子结点要小
随便n元素的数,按照完全二叉树方式放入一个数组,生成最小堆:
1、从最后一个非叶结点(结点数组编号为n/2)开始,对该结点和下面的左右叶结点进行比较,使最小的数放在非叶结点上。
2、扫描完这层后,开始扫描上一层,该结点如果要移位,就需要对下面及下面的叶结点进行比较,使其符合最小堆要求,不移位不比较。
3、重复,直到扫描到根节点(结点编号为1)为止。
时间复杂度O(N)
5、堆排序
时间复杂度和快速排序一样O(NlogN)。
以从小到大排序为例。
1、生成最大堆
2、把数组中最后h[n]的数和h[1]的数进行交换,n--
3、补上来的数h[1]和子节点一层一层对比,把小的数往上移,直到不能移动时,再跳到2反复。
create();
while(n>1)
{
swap(1,n);
n--;
siftdown(1);
}
siftdown(int i)
{
while(!到底或已经没有小的)
{
n[i]和左儿子比,和右儿子比,如果有小的交换并记录在t中。
更新到交换后的结点i=t。
}
}
6、堆的应用
优先队列:普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。
二叉堆就是优先队列(父节点大于子节点)
求一个数列中第K大/小的数。
取出K个数建一个大小为K的最小/大堆,再从K+1个数开始,依次拿去和堆顶比较,如果要小/大,就舍弃,如果大/小就一层一层往下比和移。
时间复杂度O(NlogN)
并查集/不相交集数据结构的算法:
通过一个数组来实现,其本质是维护一个森林,刚开始的时候,森林的每个点都是孤立的,可理解成一个结点的树,
之后通过一些条件,逐步将这些树合并成一棵大树。判断两个节点是否已经在同一棵树(数其实是个集合)中的时候,
也要注意必须求其根源,中间父亲节点是不能说明问题的,必须找到其祖宗判断两个结点的祖宗是否是同一个根结点才行。
0 0
- 算法三:树和堆排序
- 排序算法(三):堆排序
- 【算法】堆和堆排序
- 三、算法_堆排序
- 算法三之堆排序
- 算法三之堆排序
- 排序算法之堆和堆排序
- 排序算法—堆和堆排序
- 几大内部排序算法(三)--堆(优先队列)和堆排序
- Java排序算法(三):堆排序
- 排序算法(三):堆排序
- 浅谈排序算法(三)之堆排序
- Java排序算法(三):堆排序
- 排序算法三之堆排序
- Java排序算法(三):堆排序
- Java排序算法(三):堆排序 .
- 排序算法(三)-- 堆排序
- Java排序算法(三):堆排序
- Jenkins(Hudson)实现远程部署Web项目
- struts
- Bootstrip学后见习
- SAP升级数据库ASE报 kernel SySAM: Licenses exist for ASE, but a license containing the configured (PE=EE
- map、set例子
- 算法三:树和堆排序
- JVM 调优参数详解
- Flex日期触发change避免两次初始化
- 10:面向对象封装 续
- c#MVC using的用法
- JSP的9个内置对象
- Android调用手机拍照以及从相册选择照片
- JAVA中的Math类
- MTG媒体中继网关