堆排序程序及证明

      

   

堆排序:二叉树。如果按升序排列,保证父节点的值小于等于子节点的值。

堆排序证明:

1.

for i=n/2 downto 1 do

down(i);

I.每次点i向下操作前保证:以点i的子节点为根节点的子树的所有节点满足它的值小于等于其子节点的值(如果有子节点)。

II.每次点i向下操作后保证:以点i为根节点的子树的所有节点满足它的值小于等于其子节点的值(如果有子节点)。

证明:

down(i)操作中,点i的值修改后必满足“其值小于等于其子节点的值(如果有子节点) ”;对于任意交换值的两个数(子节点和父节点),修改后都满足“父节点的值小于等于其子节点的值(如果有子节点) ”;而对于其它未交换顺序的数,本来就满足“它的值小于等于其子节点的值(如果有子节点)”。所以得证。

2.每次取出a[1]的值,把a[n]的值放入a[1](n为当前堆的大小,即树节点的数目),然后对a[1]进行down操作。

证明:

根节点a[1]总可以通过某条路径到达某个点a[s],设中途经过点d1,d2,…,dk,则a[1]<=a[d1]<=a[d2]<=…<=a[dk]<=a[s],所以a[1] 保证是二叉树中的最小值。

然后对a[1]进行down操作,根据I“每次点i向下操作后保证:以点i为根节点的子树的所有节点满足它的值小于等于其子节点的值(如果有子节点)。”,所以对a[1]进行down操作后,保证当前a[1]是当前二叉树中的最小值。得证。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define maxn 10000
 4
 5 long a[maxn+1],n;
 6
 7 void down(long i)
 8 {
 9     long j,temp;
10     while (1)
11     {
12         j=i<<1;
13         if (j>n)
14             break;
15         if (j!=n && a[j]>a[j+1])
16             j++;
17         if (a[i]>a[j])
18         {
19             temp=a[i];
20             a[i]=a[j];
21             a[j]=temp;
22         }
23         else
24             break;
25         i=j;
26     }
27 }
28
29 int main()
30 {
31     long nn,i;
32     scanf("%ld",&n);
33     for (i=1;i<=n;i++)
34         scanf("%ld",&a[i]);
35     for (i=n >>1;i>=1;i--)
36         down(i);
37     nn=n;
38     for (i=1;i<=nn;i++)
39     {
40         printf("%ld ",a[1]);
41         a[1]=a[n];
42         n--;
43         down(1);
44     }
45     return 0;
46 }
时间: 2024-10-25 06:40:16

堆排序程序及证明的相关文章

堆排序程序中的小于等于号问题

做堆排序问题时遇到一个bug,调试了很久才发现原因,是一个小于号和小于等于号的问题,在递归时的边界没考虑周全.代码用java写的,拿出来分析下,首先是网上比较多的使用大于号控制边界的程序: import java.util.*; public class MaxHeap { public static int[] heapSort(int[] A, int n) { // write code here MakeMaxHeap(A,n-1); System.out.println("build

一个复杂的堆排序程序

用堆排序的方法实现将数组中的数字从小到大排列. 编译器:gcc, 编译环境:32位系统可以正常编译; 如果是64位系统请使用 -m32参数, 或修改宏定义中的汇编代码部分. #include<stdio.h> #include<stdlib.h> #include<strings.h> #define push(x) __asm__ volatile ("push %%eax" ::"a"(x)) #define pop() ({

为什么国外程序员爱用 Mac?

from http://www.vpsee.com/2009/06/why-programmers-love-mac/ Mac 在国外很受欢迎,尤其是在 设计/web开发/IT 人员圈子里.普通用户喜欢 Mac 可以理解,毕竟 Mac 设计美观,简单好用,没有病毒.那么为什么专业人士也对 Mac 情有独钟呢?从个人使用经验来看我想有下面几个原因: 1.Mac OS X 是基于 Unix 的.这一点太重要了,尤其是对开发人员,至少对于我来说很重要,这意味着Unix 下一堆好用的工具都可以随手捡到.

对 Web 应用程序进行性能调优

动态的 Web 应用程序能够存储大量信息,让用户能够通过熟悉的界面立即访问这些信息.但是,随着应用程序越来越受欢迎,可能会发现对请求的响应速度没有以前那么快了.开发人员应该了解 Web 应用程序处理 Web 请求的方式,知道在 Web 应用程序开发中可以做什么,不能做什么,这有助于减少日后的麻烦. 静态的 Web 请求(比如图 1 所示的请求)很容易理解.客户机连接服务器(通常通过 TCP 端口 80),使用 HTTP 协议发出一个简单的请求. 图 1. 客户机通过 HTTP 请求静态的文件 服

堆排序的算法分析

堆排序算法分析 什么是堆 我们这里讨论的堆是一种数据结构,而不是垃圾收集存储机制.(二叉)堆一个数组,它可以被看成一个近似的完全二叉树,即一棵树上的每一个结点对应数组中的某一个元素,除了最底层外,该树是完全填满的,而且是从左往右填充.堆具有三个重要的属性,即父结点.左孩子.右孩子.堆又分为两种,即最大堆和最小堆,最大堆是指所有的父结点都要大于子结点,故根结点的"值"最大(这里堆中存储的不一定是数值,可以是任何一种对象,只要实现了相应的equals()方法即可,下文中将以简单的int数值

Java程序员实现月薪3万需要具备哪些技能?

抛开工作经验,项目经验,学历背景,单从技术点分析,哪些方面可以判断一个java程序员的技术扎实程度,怎样才能知道他值多少月薪呢?本文将为你解答: 本着理论结合实践的方法,我一般都不问上面这种纯知识和理论性问题,而是让他写一段程序来证明HashMap是线程不安全的.然后,再让改一下这个程序,使之线程安全. 在 面试等情况下,如果有条件,最好能给被考核人一台可以上Google的电脑,然后给其一段自己的空间和时间,比如一个人在小会议室里10-20分钟.然 后,另接一台显示器,同步观察他在电脑上是怎么做

Java程序员实现月薪2万需要具备哪些技能?

抛开工作经验,项目经验,学历背景,单从技术点分析,哪些方面可以判断一个java程序员的技术扎实程度,怎样才能知道他值多少月薪呢?本文将为你解答: 本着理论结合实践的方法,我一般都不问上面这种纯知识和理论性问题,而是让他写一段程序来证明HashMap是线程不安全的.然后,再让改一下这个程序,使之线程安全. 在面试等情况下,如果有条件,最好能给被考核人一台可以上Google的电脑,然后给其一段自己的空间和时间,比如一个人在小会议室里10-20分钟.然后,另接一台显示器,同步观察他在电脑上是怎么做的.

培训班出身的程序员为什么遭人嫌弃

这几年,由于it软件行业对人才的需求很大,很多传统行业也纷纷创办"互联网+"项目,加上app开发热潮,微信公众平台也催生了更多的就业岗位.于是it从业人员的薪水也随之水涨船高.同时it培训班也随雨后春笋般涌出,一个个打出的口号都很响."0基础入学,三个月包就业""毕业月入不过万,不收学费""从前是你找工作,接下来是工作找你"真是人有多大胆,口号就有多不要脸. 对于迫切想改变自己境遇的人来说,这些口号无疑是很具诱惑力的.在培训机

2019小程序对于创业者来说有怎样的变化

小程序在2017年初上线,经过二年的沉淀之后,去年迎来了全面的爆发.虽然这个事实让很多人感到意外同时又在意料之中,但小程序确实正在成为大佬们口中"改变未来互联网格局的产物",与此同时,小程序的流量红利也在今年开始逐渐显现.那么对于商家和创业者来说,小程序在2019年会发生哪些令人期待的变化呢? 流量 作为线上产品,流量是每一个商家和创业者都无法避之不谈的话题.小程序的特点是轻松快捷用过即走,但这样的特性也是一把双刃剑,用户用过即走之后,是否就意味着流失了流量呢?而如何让用户即用即走的同