为防止广告,目前nocow只有登录用户能够创建新页面。如要创建页面请先登录/注册(新用户需要等待1个小时才能正常使用该功能)。

二叉堆/C++

来自NOCOW
跳转到: 导航, 搜索

C++非STL大根堆、小根堆实现:

//By Stanso
#include <iostream>
using namespace std;
#define MAX_LONG 2147483647
 
class binary_heap
{
      protected:
      long cnt;
      long h[100000];
      binary_heap() {cnt=0;h[0]=0;}//其实h[0]没用 
      long pre(long n) {return n>>1;}
      long lch(long n) {return n<<1;}
      long rch(long n) {return (n<<1)+1;}
 
      public:
	  long size(){return cnt;}
};
class maxheap:public binary_heap
{
      public:
      void ins(long n)
      {
           int p=++cnt;//元素个数+1,p指向堆底 
           while(p>1 && n>h[pre(p)])//若没到堆顶 且 待插入元素大于p的父亲 
                {
                 h[p]=h[pre(p)];//则把p的父亲移到他儿子的地方(就是p的地方) 
                 p=pre(p);//p指向它的父亲 
                }
           h[p]=n;//最后把待插入元素放入p的地方 
      }
      long pop()
      {
	      if(cnt==0) return -MAX_LONG;//返回-MAX_LONG视为错误
	      long p=1;
		  long ans=h[1];
		  long tmp=h[cnt--];//取出堆底元素然
	      long to;
		  while(p<=cnt)//若未到栈底
		       {
			    to=-MAX_LONG;//init
			    if(lch(p)<=cnt && tmp<h[lch(p)])//若有左孩子且比取出的栈底元素大
				  to=lch(p);
				if(rch(p)<=cnt && tmp<h[rch(p)] && h[to]<h[rch(p)])//若有右孩子 且 比取出的栈底元素大 且 大于左孩子
				  to=rch(p);
				if(to!=-MAX_LONG) {h[p]=h[to];p=to;}//如果比左右孩子都大,就说明找对位置了,把取出的栈底放上去;否则交换
				else{h[p]=tmp;break;}
			   }
 
		  return ans;
	  }
};
class minheap:public binary_heap
{
      public:
      void ins(long n)
      {
           int p=++cnt;//元素个数+1,p指向堆底 
           while(p>1 && n<h[pre(p)])//若没到堆顶 且 待插入元素小于p的父亲 
                {
                 h[p]=h[pre(p)];//则把p的父亲移到他儿子的地方(就是p的地方) 
                 p=pre(p);//p指向它的父亲 
                }
           h[p]=n;//最后把待插入元素放入p的地方 
      }
      long pop()
      {
	      if(cnt==0) return -MAX_LONG;//返回-MAX_LONG视为错误
	      long p=1;
		  long ans=h[1];
		  long tmp=h[cnt--];//取出堆底元素然
	      long to;
		  while(p<=cnt)//若未到栈底
		       {
			    to=-MAX_LONG;//init
			    if(lch(p)<=cnt && tmp>h[lch(p)])//若有左孩子且比取出的栈底元素小
				  to=lch(p);
				if(rch(p)<=cnt && tmp>h[rch(p)] && h[to]>h[rch(p)])//若有右孩子 且 比取出的栈底元素小 且 小于左孩子
				  to=rch(p);
				if(to!=-MAX_LONG) {h[p]=h[to];p=to;}//如果比左右孩子都小,就说明找对位置了,把取出的栈底放上去;否则交换
				else{h[p]=tmp;break;}
			   }
 
		  return ans;
	  }
};
 
minheap h1;
 
int main()
{
   long tmp;
   while(cin >>tmp)
        h1.ins(tmp);
   cout <<endl<<"SIZE:"<<h1.size()<<endl<<endl;
   for(long i=h1.size();i>0;i--)
      cout <<h1.pop()<<endl;
   system("pause");
}

下面是C++模板实现堆排序:

#include<iostream>
#include<vector>
using namespace std;
 
namespace Heap
{
template <class T>
class BinaryHeap
{
  vector<T> h;
  int n;
public:
  BinaryHeap();
  BinaryHeap(const T &err);
  void max_heapify(int i);
  void min_heapify(int i);
  void insert(const T &e);
  T minnum() const;
  T extract_min();
  void decrease_key(int x,const T &k);
  void kill(int x);
};
template<class T>
BinaryHeap<T> heap_union(const BinaryHeap<T> &h1,const BinaryHeap<T> &h2);
}
 
template<class T>
Heap::BinaryHeap<T>::BinaryHeap()
{
  h.push_back(T ());
  n=1;
}
 
template<class T>
Heap::BinaryHeap<T>::BinaryHeap(const T &err)
{
  h.push_back(err);
  n=1;
}
 
template<class T>
void Heap::BinaryHeap<T>::max_heapify(int i)
{
  for(;i>1;)
  {
    int p=i>>1;
	if(h[i]<h[p])
	{
	  T temp(h[i]);
	  h[i]=h[p];
	  h[p]=temp;
	  i=p;
	}
	else
	  break;
  }
}
 
template<class T>
void Heap::BinaryHeap<T>::min_heapify(int i)
{
  if(i<1 ||i>=n)
    return;
  for(;;)
  {
    int left=i<<1;
	int right=left+1;
	int smallest;
	if(left>=n)
	  break;
	if(right>=n)
	  smallest=left;
	else
	{
	  if(h[left]<h[right])
	    smallest=left;
	  else
	    smallest=right;
	}
	if(h[smallest]<h[i])
	{
	  T temp(h[i]);
	  h[i]=h[smallest];
	  h[smallest]=temp;
	  i=smallest;
	}
	else
	  break;
  }
}
 
template<class T>
void Heap::BinaryHeap<T>::insert(const T &e)
{
  if(n>=h.size())
    h.push_back(e);
  else
    h[n]=e;
  n++;
  max_heapify(n-1);
}
 
template<class T>
T Heap::BinaryHeap<T>::minnum() const
{
  if(n>1)
    return h[1];
  return h[0];
}
 
template<class T>
void Heap::BinaryHeap<T>::decrease_key(int x,const T &k)
{
  if(h[x]<k)
    return;
  h[x]=k;
  max_heapify(x);
}
 
template<class T>
void Heap::BinaryHeap<T>::kill(int x)
{
  if(x>=1 && x<n)
  {
    h[x]=h[n-1];
	min_heapify(x);
	n--;
  }
}
 
template<class T>
T Heap::BinaryHeap<T>::extract_min()
{
  if(n>1)
  {
    T min=h[1];
	kill(1);
	return min;
  }
  return h[0];
}
 
int main()
{
  int a[]={12,3,2,43,54,32,154,21,1};
  int n=sizeof(a)/sizeof(int),i;
  Heap::BinaryHeap<int> bh;
  for(i=0;i<n;++i)
    bh.insert(a[i]);
  for(i=0;i<n;++i)
    cout<<bh.extract_min()<<' ';
  cout<<endl;
 
  return 0;
}
                                                                                         ---By D.puppet
个人工具