堆排(大顶堆,小顶堆)

堆排(大顶堆,小顶堆)

分类: 数据结构 算法相关   2289人阅读  评论(4)  收藏  举报

汗,别人都说大小顶堆只是改改大于号的问题,可我的代码从大顶堆只改动大于号调整为小顶堆竟然越界乐,掣肘!!

后来几经更改才发现是传参的问题(见代码),看来大顶堆改小顶堆不是¥%…#¥…,亦或是我RP出点问题???搞笑的是代码砖头(C::B)竟然对越界错各种容忍,于是乎平常尽量少用,孰不知越界问题很严重。。放码子:

  1. #include<iostream>//大顶堆  
  2. using namespace std;  
  3. void heap(int *p_a,int head,int tail)//调整成为一个大顶堆  
  4. {  
  5.     int tmp;  
  6.     tmp=p_a[head];//暂存根节点  
  7.     int j;  
  8.     for(j=2*head;j<=tail;j*=2)//沿节点值较大的儿子往下层筛选,2*j是左儿子,2*j+1是右儿子  
  9.     {  
  10.         if(j<tail && p_a[j]<p_a[j+1])//如果右儿子大于左儿子,j++转移到右儿子  更改大小的地方  
  11.             ++j;  
  12.         if(tmp>=p_a[j])//更改大小的地方  
  13.             break;  
  14.         p_a[head]=p_a[j];//较大的儿子向父节点平移,并更新head节点的位置  
  15.         head=j;  
  16.     }  
  17.     p_a[head]=tmp;//将根节点放置到最后空出的合适的位置  
  18. }  
  19. void h_sort(int *pz,int len)  
  20. {  
  21.     int i;  
  22.     for(i=len/2;i>0;--i)//初建大顶堆,根是个最大的,叶子们最小  
  23.         heap(pz,i,len);  
  24.     int tmp;  
  25.     tmp=pz[0];  
  26.     pz[0]=pz[len-1];  
  27.     pz[len-1]=tmp;//以上为交换堆顶和堆底,下面开始调整一次,交换一次  
  28.     for(i=len-1;i>1;--i)//从根开始调整,调完后交换堆顶和堆底***********小顶堆竟然从len开始调整  
  29.     {  
  30.         heap(pz,0,i);  
  31.         tmp=pz[0];  
  32.         pz[0]=pz[i];  
  33.         pz[i]=tmp;  
  34.     }  
  35. }  
  36. int main()  
  37. {  
  38.     int n;  
  39.     int pz[100];  
  40.     scanf("%d",&n);  
  41.     int i;  
  42.     for(i=0;i<n;++i)  
  43.         scanf("%d",&pz[i]);  
  44.     h_sort(pz,n);  
  45.     for(i=0;i<n;++i)  
  46.         printf("%d ",pz[i]);  
  47.     return false;  
  48. }  
  49. ************************小顶堆**********  
  50. #include<iostream>  
  51. using namespace std;  
  52. void heap(int *p_a,int head,int tail)//调整成为一个小顶堆  
  53. {  
  54.     int tmp;  
  55.     tmp=p_a[head];//暂存根节点  
  56.     int j;  
  57.     for(j=2*head;j<=tail;j*=2)//沿节点值较小的儿子往下层筛选,2*j是左儿子,2*j+1是右儿子  
  58.     {  
  59.         if(j<tail && p_a[j]>p_a[j+1])//如果右儿子小于左儿子,j++转移到右儿子  
  60.             ++j;  
  61.         if(tmp<=p_a[j])  
  62.             break;  
  63.         p_a[head]=p_a[j];//较小的儿子向父节点平移,并更新head节点的位置  
  64.         head=j;  
  65.     }  
  66.     p_a[head]=tmp;//将根节点放置到最后空出的合适的位置  
  67. }  
  68. void h_sort(int *pz,int len)  
  69. {  
  70.     int i;  
  71.     for(i=len/2;i>0;--i)//初建小顶堆,根节点值最小的,叶子们最最大  
  72.         heap(pz,i,len);  
  73.     int tmp;  
  74.     /*tmp=pz[0]; 
  75.     pz[0]=pz[len-1]; 
  76.     pz[len-1]=tmp;*///以上为交换堆顶和堆底,下面开始调整一次,交换一次  
  77.     for(i=len;i>1;--i)//从根开始调整,调完后交换堆顶和堆底,小顶堆竟然跟大顶堆不一样的起点  
  78.     {//既然不一样,那上面初始的调整就多余了  
  79.         heap(pz,0,i);  
  80.         tmp=pz[0];  
  81.         pz[0]=pz[i];  
  82.         pz[i]=tmp;  
  83.     }  
  84. }  
  85. int main()  
  86. {  
  87.     int n;  
  88.     int pz[1000];  
  89.     scanf("%d",&n);  
  90.     int i;  
  91.     for(i=0;i<n;++i)  
  92.         scanf("%d",&pz[i]);  
  93.     h_sort(pz,n);  
  94.     for(i=0;i<n;++i)  
  95.         printf("%d ",pz[i]);  
  96.     return false;  
  97. }  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值