手写堆

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10;
/**
小根堆,size个元素的序列满足 k[i] <= k[2 * i] && k[i] <= k[2 * i + 1] (1 <= i <= size / 2)
每次去除堆顶元素,只需要重新调整为堆即可

push一个元素,相当于在对应的层上插入一个元素,这条链上下面的元素对应向下移
pop一个元素 将堆顶元素和最后一个元素交换,再重新调整堆
调整堆  由于除了堆顶元素之外,其余结点都符合堆的条件,所以只需要把堆顶元素调整到合适的位置即可,
交换的时候 只会影响一边,所以复杂度就相当于深度
*/
int total_cnt;
struct Heap {
   int data[MAXN];
   int size;
   void clear(){size = 0;}
   int get_size(){return size;}
   bool is_empty(){return size == 0;}
   void swim(int pos){
        while(pos << 1 <= size){
            int l = pos << 1;
            if(l + 1 <= size && data[l + 1] < data[l]) l++;
            if(data[l] < data[pos]){
                swap(data[l],data[pos]);pos = l;
            }else break;
        }
   }
   void push(int value){
        data[++size] = value;
        int pos = size;
        while(pos > 1){
            if(data[pos >> 1] > data[pos]){
                swap(data[pos >> 1],data[pos]);
                pos >>= 1;
            }else break;
        }
   }
   int top(){return data[1];}
   void pop(){
        swap(data[1],data[size]);size--;
        swim(1);
   }
} h ;
char s[1010];

/**
hdu 1106测试
*/
int main(){

  while(~scanf("%s",s)){
    int len = strlen(s);
    h.clear();
    int sum = 0;
    for(int i = 0;i < len;i++){
        if(s[i] != '5') sum = sum * 10 + s[i] - '0';
        else{
            if(i && s[i-1] != '5')  h.push(sum);
            sum = 0;
        }
    }
    if(s[len-1] != '5') h.push(sum);
    while(!h.is_empty()){
        if(h.get_size() == 1) printf("%d\n",h.top());
        else printf("%d ",h.top());
        h.pop();
    }
  }
  return 0;
}
posted @ 2017-09-26 20:41  jiachinzhao  阅读(210)  评论(0编辑  收藏  举报