首页 > 代码库 > 堆排序程序及证明
堆排序程序及证明
堆排序:二叉树。如果按升序排列,保证父节点的值小于等于子节点的值。
堆排序证明:
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 }
堆排序程序及证明
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。