C++数据结构——堆,二叉搜索树及Huffman编码输出

最大堆的插入删除初始化

Huffman树的构造,输出huffman编码

搜索二叉树的插入删除输出

以下作为模板类,方法均在头文件中,否则报错

一共九个类~~~~~~

第一个,树节点BinaryTreeNode.h

template <class T>
  class BinaryTree;
template <class T>
class BinaryTreeNode 
{
   friend class BinaryTree<T>;
   friend void Visit(BinaryTreeNode<T> *);
   friend void PreOrder(BinaryTreeNode<T> *);
   friend void InOrder(BinaryTreeNode<T> *);
   friend void PostOrder(BinaryTreeNode<T> *);
   friend void LevelOrder(BinaryTreeNode<T> *);
   friend void main(void);
public:
 BinaryTreeNode(){ LeftChild=RightChild=0;}
 virtual ~BinaryTreeNode(){}
  BinaryTreeNode(const T& e)
     {
 data=e;
 LeftChild=RightChild=0;
 }
 BinaryTreeNode(const T& e,BinaryTreeNode *l,BinaryTreeNode *r)
     { 
 data=e;
 LeftChild=l;
 RightChild=r;
 }
 void Delete(){delete LeftChild;delete RightChild;delete t;}
 T data;

 BinaryTreeNode<T> *LeftChild,*RightChild;
};

 

第二个,树BinaryTree.h

#include "BinaryTreeNode.h"
#include "iostream.h"
#include "Chain.h"
#include "Huffman.h"
#include "MinHeap.h"
#include <string>

using   namespace   std;

 

template <class T>
class BinaryTree 
{
public:
 BinaryTree(){ root=0;}
 virtual ~BinaryTree(){}
    bool IsEmpty() const{}
 bool Root(T& x) const;

 void MakeTree(const T& element,BinaryTree<T>& left,BinaryTree<T>& right)
    {
      root=new BinaryTreeNode<T>(element,left.root,right.root);
      left.root=right.root=0;
 }


 void BreakTree(T& element,BinaryTree<T>& left,BinaryTree<T>& right);
    //遍历~~~
 void PreOrder(void(*Visit)(BinaryTreeNode<T> *u));
 void InOrder(void(*Visit)(BinaryTreeNode<T> *u));
 void PostOrder(void(*Visit)(BinaryTreeNode<T> *u));

 void LevelOrder(void(*Visit)(BinaryTreeNode<T> *u))//用NOde自己做个队列~~~
 {
 BinaryTreeNode<T> *queue[50];//设置一个Node指针数组
 int front=0;//队列头
 int tail=1;//队列尾
 BinaryTreeNode<T> *t;//临时变量,以防传入参访问时改变原树
 t=root;
 queue[tail]=t;//初始存入,在尾部
  while(front!=tail)
            {
                front++;
                cout<<queue[front]->data<<" ";//输出头,第一个元素
                if(queue[front]->LeftChild!=NULL)//左不为空,加入队尾
                {
                    tail++;
                    queue[tail]=queue[front]->LeftChild;
                }
                if(queue[front]->RightChild!=NULL)//右不为空,加入队尾
                {
                    tail++;
                    queue[tail]=queue[front]->RightChild;
                }//循环知道结束
            }

}


 //得到高度
 int Height() const{return Height(root);}
 //输入前中,输出后用到的三个方法
 void GetPost(int a[],int s1,int e1,int b[],int s2,int e2,int cot );
    int Find(int sourc[],int des ,int cout );
 void InputTree(int a[],int cot);
 
 //得到节点数的两个方法~
 int Size()
 {
  count=0;
  PreOrder(Add1,root);
  return count;
 }
    static void Add1(BinaryTreeNode<T> *t){count++;}
   

 static void Output(BinaryTreeNode<T> *t)
 {
  if(t->data<0)
   return;
  cout <<t->data<<" ";
 }

 //删除树/元素的方法
 static void Free(BinaryTreeNode<T> *t){delete t;}
 static void Delete1(BinaryTreeNode<T> *t)
 { 
      
  if(t->data==att)
  {
   delete t;//那么此时指向他的指针指向了个空间,再次访问时候,得到一串地址~~需要思考下
      t->LeftChild=NULL;
      t->RightChild=NULL;
   //t->data=0;
  } 

 }
 
 BinaryTree<int> HuffmanTree(int a[],int n)
 {
 Huffman<int> *w=new Huffman<int>[n+1];
 BinaryTree<int> z,zero;
 for(int i=1;i<=n;i++)
 {
  z.MakeTree(a[i],zero,zero);
  w[i].weight=a[i];
  w[i].tree=z;
 }
  
 MinHeap<Huffman<T> > H(1);
 H.Initialize(w,n,n);

 Huffman<int> x,y;
 for(i=1;i<n;i++)
 {
  H.DeleteMin(x);
  H.DeleteMin(y);
  z.MakeTree(0,x.tree,y.tree);
  x.weight+=y.weight;
  x.tree=z;
      H.Insert(x);
 }

 H.DeleteMin(x);
 H.Deactivate();
 delete [] w;
    return x.tree;
 }
 //这个方法输出huffman编码
 
void OutputCode(BinaryTree<int> huf,Chain& A,int cx,int& ze,int& on)
 {
  BinaryTreeNode<int> *t;
  t=huf.root;
  BinaryTree left,right;
 
     if(t->LeftChild )//找到原因:递归中连续几个if与if,else,if,else是有区别的,我晕
  {
   A.Insert(A.Length(),ze);
   left.root=t->LeftChild;
   OutputCode(left,A,cx,ze,on);
  }
     if(t->RightChild)
  {
   A.Insert(A.Length(),on);
   right.root=t->RightChild;
   OutputCode(right,A,cx,ze,on);
  }
    if(t->LeftChild==NULL && t->RightChild==NULL)
  {
   cout <<t->data<<"编码 : ";
   A.Output();
   A.Delete(A.Length(), cx);
   return;

  }
   if(A.Length()>=1)
   A.Delete(A.Length(), cx);
  if(A.Length()==0)
   return;
     return;

 }

 void Delete(){PostOrder(Free,root);root=0;}
 void DeleteAtt(){PostOrder(Delete1,root);}
 void PreOutput(){PreOrder(Output,root);cout<<endl;}
 void InOutput(){InOrder(Output,root);cout<<endl;}
 void PostOutput(){PostOrder(Output,root);cout<<endl;}
 void LevelOutput(){LevelOrder(Output);cout<<endl;}
  BinaryTreeNode<T> *root;
 
private:
 //static void Add1(BinaryTreeNode<T> *t){count++;}

    void PreOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t)
 {
      if(t==NULL)
    return;
      if(t)
   {
    Visit(t);
    PreOrder(Visit,t->LeftChild);
    PreOrder(Visit,t->RightChild);
   }
 }


 void InOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t)
 {
  if(t)
     {
     InOrder(Visit,t->LeftChild);
    Visit(t);
    InOrder(Visit,t->RightChild);
  }
 }

 void PostOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t);
    int Height(BinaryTreeNode<T> *t) const;
 };

 

第三个,二叉搜索树BSTree.h

#include "BinaryTreeNode.h"
template <class E,class K>
class BSTree:public BinaryTree<E>
{
public:
 BSTree(){}
 virtual ~BSTree(){}
 

bool Search(const K& k,E& e) const
 {
 BinaryTreeNode<E> *p=root;
 while(p)
  if(k<p->data) p=p->LeftChild;
  else if(k>p->data) p=p->RightChild;
  else
  {
   e=p->data;
   return true;
  }
     return false;
 }

 BSTree<E,K>& Insert(const E& e)
 {
        BinaryTreeNode<E> *p=root,*pp=0;
  while(p)
  {
   pp=p;
   if(e<p->data) p=p->LeftChild;
       else if(e>p->data) p=p->RightChild;
    else throw OutOfBounds();
  }

        BinaryTreeNode<E> *r=new BinaryTreeNode<E>(e);
  if(root)
  {
   if(e<pp->data) pp->LeftChild=r;
   else pp->RightChild=r;
  }
  else
   root=r;

 return *this;
 }


 BSTree<E,K>& Delete(const K& k,E& e)
 {
         BinaryTreeNode<E> *p=root,*pp=0;
   while(p && p->data!=k)
   {
    pp=p;
    if(k<p->data) p=p->LeftChild;
    else p=p->RightChild;
   }
   if(!p) throw OutOfBounds();

   e=p->data;

   if(p->LeftChild && p->RightChild)
   {
             BinaryTreeNode<E> *s=p->LeftChild,*ps=p;
    while(s->RightChild)
    {
     ps=s;
     s=s->RightChild;
    }

    p->data=s->data;
    p=s;
    pp=ps;
   }

   BinaryTreeNode<E> *c;
   if(p->LeftChild) c=p->LeftChild;
   else c=p->RightChild;

   if(p==root) root=c;
   else
   {
    if(p==pp->LeftChild)
     pp->LeftChild=c;
    else
     pp->RightChild=c;
   }
  
   delete p;
   return *this;


 }

void Ascend(){InOutput();}

};

 

第四个,链表Chain.h,Chain.cpp~~~用VC的在建的时候记得改名字

class ChainNode 
{
 
 
public:
 friend class Chain;
    int data;
 ChainNode *link;

};

class Chain 
{
public:
   
 Chain();
 virtual ~Chain();
 int Length() const;
 int Search(const int&x) const;
 Chain& Delete(int k,int& x) ;
    Chain& Insert(int k,int& x);
 Chain& Append(int& x);
 Chain& DeleteLast();
    void Output();
   
 ChainNode *first;
 

};

 

 

#include "Chain.h"
#include "iostream.h"
//
// Construction/Destruction
//

Chain::Chain()
{
 first =0;
 
}

Chain::~Chain()//析构
{
 
    ChainNode *next;
 while(first )
 {
  next=first->link;
  //delete first;
  first=next;
 }

}
int Chain::Length() const//获得链表大小
{
    ChainNode *current=first;
 int len=0;
 while(current)
 {
  len++;
  current=current->link;
 }
 return len;
}
int Chain::Search(const int&x) const//搜索一个值
{
 ChainNode *current=first;
 int index=1;
 while(current && current->data !=x)
 {
  current=current->link;
  index++;
 }
 if(current)  return index;
 return 0;
}
void Chain::Output()
{
 ChainNode *current=first;
 
 while(current)
 {
  cout <<current->data;
  current=current->link;
 }
 cout <<endl;
 
}
Chain& Chain::Delete(int k,int& x) //删除地k个元素,并保存在x中
{

 if(k<1 || !first)//k小于一~~为什么??
 {
  cout << "ERROR: OutOfBound  AAAA";
  return *this;
 }
 ChainNode *p=first;
 if(k==1)
  first=first->link;
 else
 {
  ChainNode *q=first;
  for(int index=1;index<k-1 && q;index++)
   q=q->link;
  if(!q || !q->link)
  {
  cout << "ERROR: OutOfBound BBBB";
  return *this;
  }
  p=q->link;
  q->link=p->link;
 }
 x=p->data;
 delete p;
 return *this;
}
Chain& Chain::Insert(int k,int& x)//在第k个元素后插入x
{
 if(k<0)
 {
  cout << "ERROR: OutOfBound CCCC";
  return *this;
 }
 ChainNode *p=first;
 for(int index=1;index<k && p;index++)
  p=p->link;

 if(k>0 && !p)
 {
  cout << "ERROR: OutOfBound DDDD";
  return *this;
 }
 
 ChainNode *y=new ChainNode;
    y->data=x;
 if(k)
 {
  y->link=p->link;
  p->link=y;
 }
 else
 {
  y->link=first;
  first=y;
 }
 return *this;
}

第五个Huffman.h~~~提供节点信息,具体操作在 BinaryTree中

#include "BinaryTree.h"
template <class T>
class Huffman 
{
 friend BinaryTree<int> HuffmanTree(T [],int);
public:
 
 virtual ~Huffman(){}
 //暂时注解~~~
 operator T () const {return weight;}

 BinaryTree<int> tree;
 T weight;

};

第六个,最大堆 MaxHeap.h

#include "iostream.h"
template <class T>
class MaxHeap 
{
public:

 MaxHeap(int MinHeapSize=10)
 {
 MaxSize=10;
 heap=new T[MaxSize+1];
 CurrentSize=0;
 }

 virtual ~MaxHeap(){delete [] heap;}

 int Size() const {return CurrentSize;}

 int Max()
 {
  if(CurrnetSize==0) throw OutOfBounds();
  return heap[1];
 }

 MaxHeap<T>& Insert(const T& x)
 {
 if(CurrentSize==MaxSize);//throw NoMem();

 int i=++CurrentSize;
 while(i !=1 && x>heap[i/2])
 {
  heap[i]=heap[i/2];
  i/=2;
 }
 heap[i]=x;
 return *this;
 }

 MaxHeap<T>& DeleteMax(T& x)
 {
    if(CurrentSize==0) throw OutOfBounds();
 x=heap[1];
 T y=heap[CurrentSize--];
 int i=1;
 int ci=2;
 while(ci<=CurrentSize)
 {
  if(ci<CurrentSize && heap[ci]<heap[ci+1])
   ci++;
  if(y>=heap[ci])
   break;
  heap[i]=heap[ci];
  i=ci;
  ci*=2;
 }
 heap[i]=y;
 return *this;
 }

  void Initialize(T a[],int size,int ArraySize)
 {
 delete [] heap;
 heap=a;
 CurrentSize=size;
 MaxSize=ArraySize;
 for(int i=CurrentSize/2;i>=1;i--)
 {
  T y=heap[i];
  int c=2*i;
  while(c<=CurrentSize)
  {
   if(c<CurrentSize && heap[c]<heap[c+1])
   c++;
      if(y>=heap[c])
   break;

   heap[c/2]=heap[c];
   c*=2;
  }
  heap[c/2]=y;
 }

 }
    void Deactivate(){heap=0;}
  
 int CurrentSize,MaxSize;
 T *heap;


};

 

第七个,最小堆MinHeap.h

#include "OutOfBounds.h"
template <class T>
class MinHeap 
{
public:

 MinHeap(int MinHeapSize=10)
 {
 MaxSize=MinHeapSize;
 heap=new T[MaxSize+1];
 CurrentSize=0;
 }

 void Initialize(T a[],int size,int ArraySize)
 {
 delete [] heap;
 heap=a;
 CurrentSize=size;
 MaxSize=ArraySize;
 for(int i=CurrentSize/2;i>=1;i--)
 {
  T y=heap[i];
  int c=2*i;
  while(c<=CurrentSize)
  {
   if(c<CurrentSize && heap[c]>heap[c+1])
   c++;
      if(y<=heap[c])
   break;

   heap[c/2]=heap[c];
   c*=2;
  }
  heap[c/2]=y;
 }

 }

 MinHeap<T>& DeleteMin(T& x)
 {
    if(CurrentSize==0) throw OutOfBounds();
 x=heap[1];
 T y=heap[CurrentSize--];
 int i=1;
 int ci=2;
 while(ci<=CurrentSize)
 {
  if(ci<CurrentSize && heap[ci]>heap[ci+1])
   ci++;
  if(y<=heap[ci])
   break;
  heap[i]=heap[ci];
  i=ci;
  ci*=2;
 }
 heap[i]=y;
 return *this;
 }

 MinHeap<T>& Insert(const T& x)
 {
 if(CurrentSize==MaxSize);//throw NoMem();
     
 int i=++CurrentSize;//貌似这有些问题
 while(i !=1 && x<heap[i/2])
 {
  heap[i]=heap[i/2];
  i/=2;
 } 
 heap[i]=x;
 return *this;
 }

    void Deactivate(){heap=0;}

 virtual ~MinHeap(){delete [] heap;}
 int Size() const {return CurrentSize;}
 
 int Min()
 {
  if(CurrnetSize==0) throw OutOfBounds();
  return heap[1];
 } 

 

 int CurrentSize,MaxSize;
 T *heap;
};

第八个,异常OutOfBounds()建一个就是了,可以处理,这里为空

class OutOfBounds 
{
public:
 OutOfBounds();
 virtual ~OutOfBounds();

};

 

第九个,总操作Operator.h,Operator.cpp

template <class T>
class Operator
{
public:
 Operator();
 virtual ~Operator();

};

#include "Operator.h"
#include "BinaryTree.h"
#include "BinaryTreeNode.h"
#include "Huffman.h"
#include "MaxHeap.h"
#include "Sort.h"
#include "Chain.h"
#include "BSTree.h"
#include "iostream.h"
//
// Construction/Destruction
//
template <class T>
Operator<T>::Operator()
{

}
template <class T>
Operator<T>::~Operator()
{

}

void main(void)
{
   cout <<"开始对堆,Huffman树,二叉搜索树操作"<<endl;
   int n;
   cout <<"要输入数组元素个数:";
   cin >>n;
   int *a;
   a=new int[n+1];
   cout <<"要输入数组元素【不允许有相同元素】 :"<<endl;
   for(int i=1;i<n+1;i++)
    cin >>a[i];
  
  

  
   BSTree<int,int> bstree;//搜索二叉树成功
   for(int m=1;m<n+1;m++)
    bstree.Insert(a[m]);
   cout <<"中序输出二叉搜索树:";
   bstree.InOutput();

  
  


 
  
 
   BinaryTree<int> bt;
   bt=bt.HuffmanTree(a,n);//构造树时出问题~~~解决!
   cout <<"按中序输出huffman所有元素:";
   bt.InOutput();
   cout <<"输出huffman编码"<<endl;
  
   int cx=0;
   Chain A;
   static int ze=0,on=1;
   bt.OutputCode(bt,A,cx,ze,on);
  
  
   MaxHeap<int> max;//最大堆成功
   max.Initialize(a,n,n);
   cout <<"按层输出最大堆所有元素:";
   for(int j=1;j<=n;j++)
    cout <<max.heap[j]<<" ";//有些问题~~貌似初始化失败---解决了~~汗
   cout <<endl;

   cout<<"堆排序:";//终于成功了~~~我晕ORZ~~~~
   Sort<int> sor;
   sor.HeapSort(a,n);
   for(int h=1;h<n+1;h++)
       cout <<a[h]<<" ";
   cout <<endl;

  


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值