堆操作

来源:互联网 发布:怎么激活电脑windows 编辑:程序博客网 时间:2024/04/30 12:19

#include <iostream>
#include "headnode.h"
#include "stack.h"
#include "queue.h"
#include "vector.h"
#include <assert.h>
using namespace std;

template<class T> class CHeap
{
private :
 CHeap() // 必须定义, 且为private.
 {
  maxroot == NULL;
  maxnum = 0;
  minroot == NULL;
  minnum = 0;
 } 
 CHeap(const CHeap&);            // 不实现. 
 CHeap& operator=(const CHeap&); // 不实现.  
 ~CHeap() // 可声明为public, 但这里声明为private没有错, 可被调用.
 {
  Heap_Destroy();
 }

public :
 static CHeap& GetInstance()
 {
  static CHeap theSingleton;
  return theSingleton;
 }

private:
 CHeapNode<T> *maxroot;
 int maxnum;
 CHeapNode<T> *minroot;
 int minnum;

public:
 void Heap_Create(T *data, int num);
 void Heap_Show();
 void Heap_Destroy();

 void Heap_Insert(const T data);
 void Heap_Delete(const T data);

private:
 CHeapNode<T>* CreateFullBinaryTree(T* data, int num);

 CVector<CHeapNode<T>*>* FindAdjustNode(CHeapNode<T>* root, int num, int& vectornum);

 void AdjustMaxHeap(CHeapNode<T>* adjustNode);
 void AdjustMinHeap(CHeapNode<T>* adjustNode);

 void showHeap(CHeapNode<T>* root, int num);
 void destroyHeap(CHeapNode<T>* root, int num);

 void InsertMaxHeap(const T data);
 void InsertMinHeap(const T data);
 CHeapNode<T>* FindInsertNodePos(CHeapNode<T>* root, int num);

 void DeleteMaxHeap(const T data);
 void DeleteMinHeap(const T data);
 CHeapNode<T>* FindAndSwapNode(CHeapNode<T>* root, int num, const T data);
};

template<class T> void CHeap<T>::Heap_Create(T *data, int num)
{
 assert(data != NULL);
 assert(num > 0);

 cout<<"creat fulltree:/t";
 maxroot = CreateFullBinaryTree(data, num);
 maxnum = num;
 minroot = CreateFullBinaryTree(data, num);
 minnum = num;
 cout<<" success!"<<endl;

 cout<<"adjust maxheap node:/t";
 int vectornum = 0;
 CVector<CHeapNode<T>*> *vector = FindAdjustNode(maxroot, num, vectornum);
 for (int index=vectornum-1; index>=0; index--)
 {
  AdjustMaxHeap((CHeapNode<T>*)(vector->data[index]));
 }

 cout<<endl;
 delete vector;

 cout<<"adjust minheap node:/t";
 vectornum = 0;
 vector = FindAdjustNode(minroot, num, vectornum);
 for (int index=vectornum-1; index>=0; index--)
 {
  AdjustMinHeap((CHeapNode<T>*)(vector->data[index]));
 }
 cout<<endl;
 delete vector;
}

template<class T> CHeapNode<T>* CHeap<T>::CreateFullBinaryTree(T* data, int num)
{
 CQueue<CHeapNode<T>*> *queue = new CQueue<CHeapNode<T>*>(2*num);
 assert(queue != NULL);

 CHeapNode<T>* tmpNode = new CHeapNode<T>(data[0], NULL, NULL, NULL);
 assert(tmpNode != NULL);
 CHeapNode<T>* tmpRoot = tmpNode;

 CHeapNode<T>* tmpLNode = tmpNode;
 CHeapNode<T>* tmpRNode = tmpNode;

 queue->enqueue(tmpNode);
 int currentLayerLen = 1;
 int currentnum = 1;

 while (!queue->empty())
 {
  tmpNode = queue->dequeue();

  if (currentnum < num)
  {
   tmpLNode = new CHeapNode<T>(data[currentnum], NULL, NULL, tmpNode);

   queue->enqueue(tmpLNode);
   tmpNode->left = tmpLNode;
   currentnum++;
  }
  else
  {
   break;
  }
  if (currentnum < num)
  {
   tmpRNode = new CHeapNode<T>(data[currentnum], NULL, NULL, tmpNode);

   queue->enqueue(tmpRNode);
   tmpNode->right = tmpRNode;
   currentnum++;
  }
  else
  {
   break;
  }
 }

 return tmpRoot;
}

template<class T> CVector<CHeapNode<T>*>* CHeap<T>::FindAdjustNode(CHeapNode<T>* root, int num, int& vectornum)
{

 CQueue<CHeapNode<T>*> *queue = new CQueue<CHeapNode<T>*>(2*num);
 assert(queue != NULL);

 CVector<CHeapNode<T>*> *vector = new CVector<CHeapNode<T>*>(2*num);
 assert(vector != NULL);

 CHeapNode<T>* tmpNode = root;
 int currentLayerLen = 1;

 queue->enqueue(tmpNode);
 while (!queue->empty())
 {
  int tmpLayerLen = 0;
  for (int index=0; index<currentLayerLen; index++)
  {
   tmpNode = queue->dequeue();
   if (tmpNode->left == NULL && tmpNode->right == NULL)
   {
    for (int index=0; index<vectornum; index++)
    {
     cout<<" "<<vector->data[index]->data;
    }
    delete queue;
    return vector;
   }
   if (tmpNode->left != NULL)
   {
    queue->enqueue(tmpNode->left);
    tmpLayerLen++;
   }
   if (tmpNode->right != NULL)
   {
    queue->enqueue(tmpNode->right);
    tmpLayerLen++;
   }
   vector->data[vectornum++] = tmpNode;
  }
  currentLayerLen = tmpLayerLen;
 }
 delete queue;
}

template<class T> void CHeap<T>::AdjustMaxHeap(CHeapNode<T>* adjustNode)
{
 while (adjustNode->left != NULL || adjustNode->right != NULL)
 {
  int value = INT_MIN;
  if (adjustNode->right != NULL)
  {
   value = max(adjustNode->left->data, adjustNode->right->data);
  }
  else
  {
   value = adjustNode->left->data;
  }

  if (adjustNode->data > value)
  {
   break;
  }
  if (value == adjustNode->left->data)
  {
   swap(adjustNode->data, adjustNode->left->data);
   adjustNode = adjustNode->left;
  }
  else
  {
   swap(adjustNode->data, adjustNode->right->data);
   adjustNode = adjustNode->right;
  }
 }

}

template<class T> void CHeap<T>::AdjustMinHeap(CHeapNode<T>* adjustNode)
{


 while (adjustNode->left != NULL || adjustNode->right != NULL)
 {
  int value = INT_MAX;
  if (adjustNode->right != NULL)
  {
   value = min(adjustNode->left->data, adjustNode->right->data);
  }
  else
  {
   value = adjustNode->left->data;
  }

  if (adjustNode->data < value)
  {
   break;
  }
  if (value == adjustNode->left->data)
  {
   swap(adjustNode->data, adjustNode->left->data);
   adjustNode = adjustNode->left;
  }
  else
  {
   swap(adjustNode->data, adjustNode->right->data);
   adjustNode = adjustNode->right;
  }
 }
}

template<class T> void CHeap<T>::Heap_Show()
{
 if (maxroot != NULL)
 {
  cout<<"max heap:/t";
  showHeap(maxroot, maxnum);
  cout<<endl;
 }
 if (minroot != NULL)
 {
  cout<<"min heap:/t";
  showHeap(minroot, minnum);
  cout<<endl;
 }

}

template<class T> void CHeap<T>::showHeap(CHeapNode<T>* root, int num)
{
 CQueue<CHeapNode<T>*> *queue = new CQueue<CHeapNode<T>*>(2*num);
 assert(queue != NULL);

 CHeapNode<T> *tmpNode = root;
 queue->enqueue(tmpNode);
 int currentLayerLen = 1;

 while (!queue->empty())
 {
  int tmpLayerLen = 0;

  for (int index=0; index<currentLayerLen; index++)
  {
   tmpNode = queue->dequeue();
   cout<<" "<<tmpNode->data;
   if (tmpNode->left != NULL)
   {
    queue->enqueue(tmpNode->left);
    tmpLayerLen++;
   }
   if (tmpNode->right != NULL)
   {
    queue->enqueue(tmpNode->right);
    tmpLayerLen++;
   }
  }
  currentLayerLen = tmpLayerLen;
 }
 delete queue;
}

template<class T> void CHeap<T>::Heap_Destroy()
{
 if (maxroot != NULL)
 {
  cout<<"destroy maxheap:/t";
  destroyHeap(maxroot, maxnum);
  cout<<" success!"<<endl;
  maxroot = NULL;
  maxnum = 0;
 }
 if (minroot != NULL)
 {
  cout<<"destroy minheap:/t";
  destroyHeap(minroot, minnum);
  cout<<" success!"<<endl;
  minroot = NULL;
  minnum = 0;
 }
}

template<class T> void CHeap<T>::destroyHeap(CHeapNode<T>* root, int num)
{
 CQueue<CHeapNode<T>*> *queue = new CQueue<CHeapNode<T>*>(2*num);
 assert(queue != NULL);

 CHeapNode<T> *tmpNode = root;
 queue->enqueue(tmpNode);
 int currentLayerLen = 1;

 while (!queue->empty())
 {
  int tmpLayerLen = 0;

  for (int index=0; index<currentLayerLen; index++)
  {
   tmpNode = queue->dequeue();
   if (tmpNode->left != NULL)
   {
    queue->enqueue(tmpNode->left);
    tmpLayerLen++;
   }
   if (tmpNode->right != NULL)
   {
    queue->enqueue(tmpNode->right);
    tmpLayerLen++;
   }
   delete tmpNode;
  }
  currentLayerLen = tmpLayerLen;
 }

 delete queue;
}

template<class T> void CHeap<T>::Heap_Insert(const T data)
{
 if (maxroot != NULL)
 {
  cout<<"Insert max heap node:/t";
  InsertMaxHeap(data);
  cout<<endl;
 }
 if (minroot != NULL)
 {
  cout<<"Insert min heap node:/t";
  InsertMinHeap(data);
  cout<<endl;
 }

 maxnum++;
 minnum++;
}

template<class T> CHeapNode<T>* CHeap<T>::FindInsertNodePos(CHeapNode<T>* root, int num)
{
 CQueue<CHeapNode<T>*> *queue = new CQueue<CHeapNode<T>*>(2*num);
 assert(queue != NULL);

 CHeapNode<T>* tmpNode = root;
 int currentLayerLen = 1;

 queue->enqueue(tmpNode);
 while (!queue->empty())
 {
  int tmpLayerLen = 0;
  for (int index=0; index<currentLayerLen; index++)
  {
   tmpNode = queue->dequeue();
   if (tmpNode->left == NULL || tmpNode->right == NULL)
   {
    delete queue;
    return tmpNode;
   }
   if (tmpNode->left != NULL)
   {
    queue->enqueue(tmpNode->left);
    tmpLayerLen++;
   }
   if (tmpNode->right != NULL)
   {
    queue->enqueue(tmpNode->right);
    tmpLayerLen++;
   }
  }
  currentLayerLen = tmpLayerLen;
 }
 delete queue;
}

template<class T> void CHeap<T>::InsertMaxHeap(const T data)
{
 CHeapNode<T>* parentNode = FindInsertNodePos(maxroot, maxnum);

 CHeapNode<T>* addNode = new CHeapNode<T>(data, NULL, NULL, parentNode);
 
 if (parentNode->left == NULL)
 {
  parentNode->left = addNode;
 }
 else
 {
  parentNode->right = addNode;
 }

 while (true)
 {
  if (parentNode != NULL && addNode->data > parentNode->data)
  {
   swap(addNode->data, parentNode->data);
   addNode = parentNode;
   parentNode = parentNode->parent;
  }
  else
  {
   break;
  }
 }
}

template<class T> void CHeap<T>::InsertMinHeap(const T data)
{
 CHeapNode<T>* parentNode = FindInsertNodePos(minroot, minnum);

 CHeapNode<T>* addNode = new CHeapNode<T>(data, NULL, NULL, parentNode);

 if (parentNode->left == NULL)
 {
  parentNode->left = addNode;
 }
 else
 {
  parentNode->right = addNode;
 }

 while (true)
 {
  if (parentNode != NULL && addNode->data < parentNode->data)
  {
   swap(addNode->data, parentNode->data);
   addNode = parentNode;
   parentNode = parentNode->parent;
  }
  else
  {
   break;
  }
 }
}

template<class T> void CHeap<T>::Heap_Delete(const T data)
{
 if (maxroot != NULL)
 {
  cout<<"Delete max heap node:/t";
  DeleteMaxHeap(data);
  cout<<endl;
 }
 if (minroot != NULL)
 {
  cout<<"Delete min heap node:/t";
  DeleteMinHeap(data);
  cout<<endl;
 }
}

template<class T> CHeapNode<T>* CHeap<T>::FindAndSwapNode(CHeapNode<T>* root, int num, const T data)
{
 CQueue<CHeapNode<T>*> *queue = new CQueue<CHeapNode<T>*>(2*num);
 assert(queue != NULL);


 CHeapNode<T>* delNode = NULL;
 CHeapNode<T>* preNode = NULL;
 CHeapNode<T>* tmpNode = root;
 int currentLayerLen = 1;

 int iLastState = -1;
 
 queue->enqueue(tmpNode);
 while (!queue->empty())
 {
  int tmpLayerLen = 0;
  for (int index=0; index<currentLayerLen; index++)
  {
   tmpNode = queue->dequeue();
   if (tmpNode->data == data)
   {
    delNode = tmpNode;
   }

   if (tmpNode->left == NULL || tmpNode->right == NULL)
   {
    if (tmpNode->left != NULL)
    {
     preNode = tmpNode->parent;
     iLastState = 0;
    }
    else
    {
     iLastState = 1;
    }
   }
   if (iLastState == -1)
   {
    preNode = tmpNode;
   }

   if (tmpNode->left != NULL)
   {
    queue->enqueue(tmpNode->left);
    tmpLayerLen++;
   }
   if (tmpNode->right != NULL)
   {
    queue->enqueue(tmpNode->right);
    tmpLayerLen++;
   }
  }
  currentLayerLen = tmpLayerLen;
 }
 delete queue;

 if (delNode == NULL)
 {
  return NULL;
 }

 tmpNode = preNode;
 if (iLastState == 0)
 {
  delNode->data = preNode->left->data;
  delete tmpNode->left;
  preNode->left = NULL;

 }
 else if (iLastState == 1)
 {
  delNode->data = preNode->right->data;
  delete tmpNode->right;
  preNode->right = NULL;
 }
 else
 {
  return NULL;
 }

}

template<class T> void CHeap<T>::DeleteMaxHeap(const T data)
{
 CHeapNode<T>* tmpNode = FindAndSwapNode(maxroot, maxnum, data);
 if (tmpNode == NULL)
 {
  cout<<"delete data not exist!"<<endl;
 }

 CHeapNode<T>* parentNode = NULL;

 while(tmpNode != NULL)
 {
  parentNode = tmpNode->parent;
  AdjustMaxHeap(tmpNode);
  tmpNode = parentNode;
 }
}

template<class T> void CHeap<T>::DeleteMinHeap(const T data)
{
 CHeapNode<T>* tmpNode = FindAndSwapNode(minroot, minnum, data);
 if (tmpNode == NULL)
 {
  cout<<"delete data not exist!"<<endl;
 }

 CHeapNode<T>* parentNode = NULL;

 while(tmpNode != NULL)
 {
  parentNode = tmpNode->parent;
  AdjustMinHeap(tmpNode);
  tmpNode = parentNode;
 }
}

原创粉丝点击