堆排序的进一步理解

堆-顾名思义,上面小,下面大,或者上面大,下面小。

在堆排序过程中,首先应该建堆。如何将数组中的元素建立成一个规范的堆行结构。

二叉堆是完全二叉树或者是近似完全二叉树。二叉堆满足二个特性:

1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。

2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。

当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆

假设根结点的下标为1,则第 i 个结点的父结点下标为 i / 2 , 第 i 个结点的左子结点的下标为2*i, 右子结点的下标为2*i+1 ;

如何才能使得数组中元素形成堆的结构呢?首先将父结点、左子结点、右子结点这三个结点看成一个小堆或者一个小三角形,叶子结点无左子结点和右子结点,所以默认叶子结点为堆结构。则最后一个元素的父结点下标为 i/2, 从 i/2 开始,直到根结点为止,小三角形的面积逐渐增大,到根结点时达到最大,也就完成了堆的建立。

接下来进行的是堆排序操作,由于根结点元素为最大元素,每次先将根结点元素和最后一个元素调换,然后再调整堆即可,直到堆中元素只剩一个时结束,这样数组中的元素就为有序的元素。具体代码如下:

#include<stdio.h>

void MaxHeap(int a[] ,  int i , int n)  {
        int j ;
        a[0] = a[i] ;
        j  = 2 * i ;
        while ( j <= n )        {
                if(j + 1 <= n && a[j + 1] > a[j])
                        j++ ;
                if(a[0] >= a[j])
                        break ;
                a[i] = a[j] ;
                i = j ;
                j = 2 * i ;
        }
        a[i] = a[0] ;
}

void MakeMaxheap(int a[] ,  int n )     {
        int i ;
        for(i = n / 2 ; i >= 1 ; i--)
                MaxHeap(a,i,n) ;
}
void swap(int &a , int &b)      {
        int t = a ;
        a = b ;
        b = t ;
}
void Delete(int a[] ,  int n )  {
        swap(a[1],a[n]) ;
//      printf("%d\n",a[1]) ;
        MaxHeap(a,1,n-1) ;
}
int main()      {
        int a[] = {0,16,4,10,14,7,9,3,2,8,1} ;
        MakeMaxheap(a,10) ;
        int i ;
        for(i = 1 ; i < 11 ; i++)
                printf("%d ",a[i]) ;
        printf("\n") ;
        return 0 ;
}
   

堆排序的进一步理解,布布扣,bubuko.com

时间: 2024-07-30 07:52:46

堆排序的进一步理解的相关文章

seach tree的deletion的实现——对树的指针的进一步理解

一颗binary search tree,我们要在其中删除node1.而node1对应的key是,比如说,key1.删除的基本想法是什么呢? 1.找到key1对应的那个node在哪里.这个用一个迭代就可以完成了. 2.删掉这个node (1)如果这个node没有左右子树,那么直接删掉就好了. (2)如果这个node只有左子树或者右子树,那么直接让左右子树缩进上来就好了. (3)如果既有左子树又有右子树,那么就从左子树里面找出最大的node,用这个node来替换掉需要删除的那个节点. 举个栗子:有

C#中委托的进一步理解

文章介绍了委托的基本知识,接下来就进一步研究一下委托. 委托类型 其实,刚开始觉得委托类型是一个比较难理解的概念,怎么也不觉得下面的"AssembleIphoneHandler"是一个类型. 代码如下: public delegate void AssembleIphoneHandler(); 按照正常的情况,如果我们要创建一个委托类型应该是: 代码如下: public class AssembleIphoneHandler : System.MulticastDelegate { }

Java内存管理的进一步理解-模拟过程图解

Java内存管理的进一步理解-模拟过程图解--转载 java的内存管理分为: 1.堆内存:2.栈内存:3.方法区:4.本地方法区 /* 1:方法区      方法区存放装载的类数据信息包括:      (1):基本信息:      1)每个类的全限定名       2)每个类的直接超类的全限定名(可约束类型转换)      3)该类是类还是接口      4)该类型的访问修饰符      5)直接超接口的全限定名的有序列表      (2):每个已装载类的详细信息:      1)运行时常量池:

通过一个WPF实例进一步理解委托和事件

在前写过"浅谈C#中的委托"和"浅谈C#中的事件"两篇博客,内容有些抽象,似乎难以说明委托和事件的关系. 今天通过一个小程序来进一步说明二者的使用及联系. 首先新建一个WPF应用程序,取名TestDelegateAndEvent. 在.xmal中加入四个按钮,并添加Window_Loaded事件. 代码如下: <Window x:Class="TestDelegateAndEvent.MainWindow" xmlns="http

进一步理解委托

前面一篇文章介绍了委托的基本知识,接下来就进一步研究一下委托. 委托类型 其实,刚开始觉得委托类型是一个比较难理解的概念,怎么也不觉得下面的"AssembleIphoneHandler"是一个类型. public delegate void AssembleIphoneHandler(); 按照正常的情况,如果我们要创建一个委托类型应该是: public class AssembleIphoneHandler : System.MulticastDelegate { } 但是,这种写法

『cs231n』卷积神经网络的可视化与进一步理解

cs231n的第18课理解起来很吃力,听后又查了一些资料才算是勉强弄懂,所以这里贴一篇博文(根据自己理解有所修改)和原论文的翻译加深加深理解. 可视化理解卷积神经网络 原文地址 一.相关理论 本篇博文主要讲解2014年ECCV上的一篇经典文献:<Visualizing and Understanding Convolutional Networks>,可以说是CNN领域可视化理解的开山之作,这篇文献告诉我们CNN的每一层到底学习到了什么特征,然后作者通过可视化进行调整网络,提高了精度.最近两年

AutoResetEvent waitone set进一步理解补充

AutoResetEvent 的定义 //定义两个信号锁 AutoResetEvent ReadTxt = new AutoResetEvent(false); AutoResetEvent UploadTxt = new AutoResetEvent(false); 默认是false 也就是关闭状态了.这里要 理解信号 锁,实际就像某大神说的,把waitone()想象成地铁的刷卡进站,就是那个刷卡器,你用set()卡刷一次,waitone()由关闭状态进入打开状态.运行完waitone下边剩下

c++ 关于引用 &amp;的进一步理解

在很久以前看primer的时候看到&有了一些理解,接着在平时使用的时候觉得自己有了更深的理解,发现书上讲得的确挺对但是却不怎么好理解,所以再写一篇来解释一下引用 & .大神勿喷,有错请指教,本人菜鸟一枚... 觉得在学习c++的时候 最重要的一个东西就是,你在学习的时候一定要搞懂它是什么? 那引用是什么呢? 其实呢引用 也是一个指针,哈哈. 为什么呢我们可以看一下 char a = 'a': char &b = a: b = 'b'; cout<<b: 代码会输出 字符

对iOS后台模式最多10分钟运行时间的进一步理解

在app进入后台时,系统初始默认是只有10s的处理时间,但如果10s不够,我们可以主动申请,网上流传最多的一个说法是10分钟. 但这种说法有个前提: 那就是iOS7之前,是这样 但从iOS7开始,我们申请后,最多只有180s的处理时间(3分钟),一直颇不理解,为什么变成了3分钟. 申请方法swift写法: var backgroundTaskIdentifier:UIBackgroundTaskIdentifier! backgroundTaskIdentifier = UIApplicatio