zoukankan      html  css  js  c++  java
  • 最小堆算法

    最小堆算法:

      1 #include <iostream>
      2 #include <fstream>
      3 #include <cstring>
      4 #include <vector>
      5 #include <queue>
      6 #include <stack>
      7 #include <algorithm>
      8 #include <cmath>
      9 
     10 using namespace std;
     11 
     12 #define loop(i,n) for(int i=0;i<(n);i++)
     13 #define loop2(i,n) for(int i=1;i<=(n);i++)
     14 
     15 const int maxn=101;
     16 int inf=99999999;
     17 
     18 int h[maxn]; //用来存放堆的数组
     19 int n; //用来存储堆中元素的个数,也就是堆的大小
     20 //交换函数,用来交换堆中的两个元素的值
     21 void swap(int x,int y)
     22 {
     23   int t;
     24   t=h[x];
     25   h[x]=h[y];
     26   h[y]=t;
     27 }
     28 
     29 void siftdown(int i)  //传入一个需要向下调整的结点编号i,这里传入1,即从w堆的顶点开始向下调整
     30 {
     31   int t,flag=0; //flag用来标记是否需要继续向下调整
     32 
     33   while(i*2<=n && flag==0) //当i结点有儿子(其实是至少有左儿子的情况下)并且有需要继续调整的时候,循环就执行
     34   {
     35     if(h[i]>h[i*2]) //首先判断它和左儿子的关系,并用t记录值较小的结点编号
     36       t=i*2;
     37     else
     38       t=i;
     39     if(i*2+1<=n) //如果有右儿子的值更小,更新较小的结点编号
     40       if(h[t]>h[i*2+1])
     41         t=i*2+1;
     42     if(t!=i) //如果发现最小的结点编号不是自己,说明子结点中有比父结点更小的
     43     {
     44       swap(t,i); //交换它们,注意swap函数需要自己来写
     45       i=t; //更新i为刚才与它交换的儿子结点的编号,便于接下来继续向下调整
     46     }
     47     else
     48       flag=1;//否则说明当前的父结点已经比两个子结点都要小了,不需要再进行调整了
     49   }
     50 }
     51 
     52 void siftup(int i) //传入一个需要向上调整的结点编号i
     53 {
     54   int flag=0; //用来标记是否需要继续向上调整
     55   if(i==1)return;//如果是堆顶,就返回,不需要调整了
     56 
     57   while(i!=1 && flag==0)//不在堆顶,并且当前结点i的值比父结点小的时候就继续向上调整
     58   {
     59     if(h[i]<h[i/2]) //判断是否比父结点的小
     60       swap(i,i/2); //交换它和它爸爸的位置
     61     else
     62       flag=1; //表示已经不需要调整了,当前结点的值比父结点的值要大
     63     i=i/2; //这句话很重要,更新编号i为它父结点的编号,从而便于下一次继续向上调整
     64   }
     65 }
     66 //删除最大的元素
     67 int deletemax()
     68 {
     69   int t;
     70   t=h[1];//用一个临时变量记录堆顶点的值
     71   h[1]=h[n];//将堆的最后一个点赋值到堆顶
     72   n--;//堆元素减少1
     73   siftdown(1); //向下调整
     74   return t;  //返回之前记录的堆的顶点的最大值
     75 }
     76 
     77 void create()
     78 {  
     79   for(int i=n/2;i>=1;i--)
     80     siftdown(i);
     81 }
     82 
     83 void heapsort()
     84 {
     85   while(n>1)
     86   {
     87     swap(1,n);
     88     n--;
     89     siftdown(1);
     90   }
     91 }
     92 
     93 
     94 void test()
     95 {   
     96   freopen("minheap.in","r",stdin);  
     97   //freopen("minheap.out","w",stdout); 
     98   int num;
     99   cin>>num;
    100   for(int i=1;i<=num;i++)
    101     cin>>h[i];
    102   n=num;
    103 
    104   create();
    105   //heapsort();
    106   //删除顶部元素,连续删除n次,其实也就是从大到小把数输出来
    107   for(int i=1;i<=num;i++)
    108     cout<<deletemax()<<" ";
    109 
    110   cout<<endl;
    111 }
    112 
    113 int main () 
    114 {        
    115     test();        
    116     return 0;
    117 }

    test data:

    14
    99 5 36 7 22 17 46 12 2 19 25 28 1 92
    /***********************************************

    看书看原版,原汁原味。

    不会英文?没关系,硬着头皮看下去慢慢熟练,才会有真正收获。

    没有原书,也要网上找PDF来看。

    网上的原版资料多了去了,下载东西也到原始下载点去看看。

    你会知其所以然,呵呵。

    ***********************************************/

  • 相关阅读:
    我的第一篇博客
    文献笔记5
    文献笔记4
    文献笔记8
    文献笔记6
    文献笔记10
    文献笔记7
    文献笔记1
    文献笔记2
    文献笔记3
  • 原文地址:https://www.cnblogs.com/dpblue/p/4059225.html
Copyright © 2011-2022 走看看