南邮数据结构实验二---二叉树的基本操作及哈夫曼编码译码系统的实现
2017-01-23 16:49
513 查看
目的:创建一棵二叉树,实现先序、中序和后序遍历一棵二叉树,
计算二叉树结点个数等操作。
哈夫曼编码/译码系统。
要求:
能成功演示二叉树的有关运算,
运算完毕后能成功释放二叉树所有结点占用的系统内存。
程序一:二叉树的创建以及基本运算
main.cpp
#include"BTree.h"
#include <cstdio>
int main()
{
BTree<char> d,e,f,b,c,a,left,right;
d.MakeTree('D',left,right);
e.MakeTree('E',left,right);
f.MakeTree('F',left,right);
b.MakeTree('B',left,d);
c.MakeTree('C',e,f); //先叶子,再根节点。
a.MakeTree('A',b,c);
a.PreOrder(Visit);
//a=c;
a.PreOrder(Visit);
a.InOrder(Visit);
a.PostOrder(Visit);
a.CenOrder(Visit);
printf("总共有 %d 个结点\n",a.CountNode());
printf("二叉树高度是 %d \n",a.GetHeight());
printf("二叉树的叶子总数是 %d\n",a.GetLeaf());
a.Exch();
cout<<"later镜面转换后"<<endl;
a.PreOrder(Visit);
char ch;
a.BreakTree(ch,left,right); //拆分树
cout<<"ch="<<ch<<endl;
cout<<"拆分后的第一个树是"<<endl;
left.PreOrder(Visit); //遍历拆分后的左子树
cout<<"拆分后的第二个树是"<<endl;
right.PreOrder(Visit); //遍历拆分后的右子树
cout<<endl;
return 0;
}
BTree.cpp
#include "head.h"
#include <iostream>
#include <queue>
#include <cstdio>
template<class T>
class BTree
{
public:
BTree(){root=NULL;}
~BTree()
{
Delete();
}
bool IsEmpty()const;
bool Root(T &x)const;
void MakeTree(const T &e ,BTree<T>& left, BTree<T>& right);
void BreakTree(T &e ,BTree<T>& left,BTree<T>& right);
void PreOrder(void (*Visit)(BTNode<T>* u))
{
cout<<"先序遍历为"<<endl;
PreOrder(Visit,root);
cout<<endl;
}
void InOrder(void (*Visit)(BTNode<T>* u))
{
cout<<"中序遍历为"<<endl;
InOrder(Visit,root);
cout<<endl;
}
void PostOrder(void (*Visit)(BTNode<T>* u))
{
cout<<"后序遍历为"<<endl;
PostOrder(Visit,root);
cout<<endl;
}
void Exch()
{
Change(root);
}
void CenOrder(void (*Visit)(BTNode<T>* u))
{
cout<<"层次遍历为"<<endl;
CenOrder(Visit,root);
cout<<endl;
}
void Delete()
{
Delete(root);
root=NULL;
cout<<"释放空间完成"<<endl;
}
int CountNode()
{
return CountNode(root);
}
int GetHeight()
{
return GetHeight(root);
}
int GetLeaf()
{
return GetLeaf(root);
}
BTNode<T> * CopyTree()const;
void operator=(const BTree<T>& copyFrom);
private:
BTNode<T>* root;
void PreOrder(void (*Visit)(BTNode<T>*u), BTNode<T>*t);
void InOrder(void (*Visit)(BTNode<T>* u), BTNode<T>*t);
void PostOrder(void (*Visit)(BTNode<T>* u), BTNode<T>*t);
void Change(BTNode<T> *t);
void CenOrder(void (*Visit)(BTNode<T>* u),BTNode<T>* t);
void Delete(BTNode<T>* p);
int CountNode(BTNode<T> *p);
int GetHeight(BTNode<T>* t);
int GetLeaf(BTNode<T> *t);
BTNode<T> * CopyTree(BTNode<T> *t)const;
};
template<class T>
int BTree<T>::GetLeaf(BTNode<T> *t)
{
if(!t)return 0;
int tmp=0;
if(t->lchild!=NULL)
{
tmp+=GetLeaf(t->lchild);
}
if(t->rchild!=NULL)
{
tmp+=GetLeaf(t->rchild);
}
if(t->lchild==NULL&&t->rchild==NULL)
{
return 1;
}
return tmp;
}
template <class T>
int BTree<T>::GetHeight(BTNode<T>* t)
{
if(!t)return 0; //若为空节点,则返回0
if((!t->lchild)&&(!t->rchild)) return 1; //若为叶子节点,则返回1
int lHeight=GetHeight(t->lchild);
int rHeight=GetHeight(t->rchild);
return (lHeight>rHeight?lHeight:rHeight)+1; //若不是叶子节点,则返回左右子树中高度最大的高度+1
}
template <class T>
int BTree<T>::CountNode(BTNode<T> *p)
{
if(p==NULL) return 0;
else return CountNode(p->lchild)+CountNode(p->rchild)+1;
}
template <class T>
void BTree<T>::Delete(BTNode<T>* p)
{
if(p==NULL) return;
if(p->lchild!=NULL)
{
Delete(p->lchild);
}
if(p->rchild!=NULL)
{
Delete(p->rchild);
}
delete p;
}
//判断二叉树是否为空
template<class T>
bool BTree<T>::IsEmpty() const
{
return root==NULL;
}
//求二叉树根结点的值
template <class T>
bool BTree<T>::Root(T &x) const
{
if (root)
{
x=root->element;
return true;
}
else return false;
}
//建造一棵二叉树,T为新生成树的根结点
//left,right为新生成树的左右子树
template <class T>
void BTree<T>::MakeTree(const T &e, BTree<T>& left, BTree<T>& right)
{
if(root||&left==&right) return;
root=new BTNode<T>(e,left.root,right.root);
left.root=right.root=NULL;
cout<<"here in BTree<T>::MakeTree"<<endl;
}
//求二叉树根结点的值,
//left,right为左右两棵子树
//此处应该修改,原树root应该为空
template <class T>
void BTree<T>::BreakTree(T &e,BTree<T>&left, BTree<T>& right)
{
cout<<"here in BTree<T>::BreakTree."<<endl;
if(left.root||right.root||!root||&left==&right) return ;
e=root->element;
left.root=root->lchild;
right.root=root->rchild;
delete root;
root=NULL;
}
template <class T>
void BTree<T>::PreOrder(void (*Visit)(BTNode<T>* u),BTNode<T>* t)
{
if(t)
{
Visit(t);
PreOrder(Visit,t->lchild);
PreOrder(Visit,t->rchild);
}
}
template <class T>
void BTree<T>::InOrder (void (*Visit)(BTNode<T>* u),BTNode<T>* t)
{
if (t)
{
InOrder(Visit,t->lchild);
Visit(t);
InOrder(Visit,t->rchild);
}
}
template <class T>
void BTree<T>::PostOrder(void (*Visit)(BTNode<T>* u),BTNode<T>* t)
{
if (t)
{
PostOrder(Visit,t->lchild);
PostOrder(Visit,t->rchild);
Visit(t);
}
}
/*实现二叉树的按层遍历,用到了一个队列(第三章中的循环队列)
首先将根结点入队列,当对列不为空的时候:取队首元素,输出队首元素,
将队首元素的左右结点入队列,删除队首元素。如此循环直到队列为空。
该程序不是递归算法。
*/
template <class T>
void BTree<T>::CenOrder(void (*Visit)(BTNode<T>* u),BTNode<T>* t)
{
if(t==NULL) return;
queue<BTNode<T>* > s;
s.push(t);
BTNode<T> *p;
while(s.empty()==0)
{
p=s.front();
Visit(p);
if(p->lchild!=NULL)
{
s.push(p->lchild);
}
if(p->rchild!=NULL)
{
s.push(p->rchild);
}
s.pop();
}
}
template <class T>
void BTree<T>::Change(BTNode<T> *t)
{
if(t)
{
Change(t->lchild);
Change(t->rchild);
BTNode<T> *p;
p=t->lchild;
t->lchild=t->rchild;
t->rchild=p;
}
}
template<class T>
BTNode<T> * BTree<T>::CopyTree()const
{
return CopyTree(root);
}
template<class T>
BTNode<T> * BTree<T>::CopyTree(BTNode<T> *t)const
{
if(t==NULL)
return NULL; //若为空树则返回NULL
BTNode<T>* pointer=new BTNode<T>(t->element); //复制当前节点
pointer->lchild=CopyTree(t->lchild);
pointer->rchild=CopyTree(t->rchild);
return pointer;
}
template<class T>
void BTree<T>::operator=(const BTree<T> & copyFrom)
{
this->Delete();
root=copyFrom.CopyTree();
}
head.h
#include <iostream>
using namespace std;
template<class T>class BTree;//Note
template<class T>
class BTNode
{
public:
BTNode(){lchild = rchild = 0;}
BTNode(const T & x){ element = x; lchild = rchild = 0;}
BTNode(const T& x,BTNode<T> *l,BTNode<T> *r)
{
element = x;
lchild = l;
rchild = r;
}
friend class BTree<T>;
friend void Visit(BTNode<T> *);
T element;
private:
BTNode<T> *lchild,*rchild;
};
template<class T>
void Visit(BTNode<T> * p )
{
cout<<p->element<<" ";
}
程序二:哈夫曼编码译码系统的实现
计算二叉树结点个数等操作。
哈夫曼编码/译码系统。
要求:
能成功演示二叉树的有关运算,
运算完毕后能成功释放二叉树所有结点占用的系统内存。
程序一:二叉树的创建以及基本运算
main.cpp
#include"BTree.h"
#include <cstdio>
int main()
{
BTree<char> d,e,f,b,c,a,left,right;
d.MakeTree('D',left,right);
e.MakeTree('E',left,right);
f.MakeTree('F',left,right);
b.MakeTree('B',left,d);
c.MakeTree('C',e,f); //先叶子,再根节点。
a.MakeTree('A',b,c);
a.PreOrder(Visit);
//a=c;
a.PreOrder(Visit);
a.InOrder(Visit);
a.PostOrder(Visit);
a.CenOrder(Visit);
printf("总共有 %d 个结点\n",a.CountNode());
printf("二叉树高度是 %d \n",a.GetHeight());
printf("二叉树的叶子总数是 %d\n",a.GetLeaf());
a.Exch();
cout<<"later镜面转换后"<<endl;
a.PreOrder(Visit);
char ch;
a.BreakTree(ch,left,right); //拆分树
cout<<"ch="<<ch<<endl;
cout<<"拆分后的第一个树是"<<endl;
left.PreOrder(Visit); //遍历拆分后的左子树
cout<<"拆分后的第二个树是"<<endl;
right.PreOrder(Visit); //遍历拆分后的右子树
cout<<endl;
return 0;
}
BTree.cpp
#include "head.h"
#include <iostream>
#include <queue>
#include <cstdio>
template<class T>
class BTree
{
public:
BTree(){root=NULL;}
~BTree()
{
Delete();
}
bool IsEmpty()const;
bool Root(T &x)const;
void MakeTree(const T &e ,BTree<T>& left, BTree<T>& right);
void BreakTree(T &e ,BTree<T>& left,BTree<T>& right);
void PreOrder(void (*Visit)(BTNode<T>* u))
{
cout<<"先序遍历为"<<endl;
PreOrder(Visit,root);
cout<<endl;
}
void InOrder(void (*Visit)(BTNode<T>* u))
{
cout<<"中序遍历为"<<endl;
InOrder(Visit,root);
cout<<endl;
}
void PostOrder(void (*Visit)(BTNode<T>* u))
{
cout<<"后序遍历为"<<endl;
PostOrder(Visit,root);
cout<<endl;
}
void Exch()
{
Change(root);
}
void CenOrder(void (*Visit)(BTNode<T>* u))
{
cout<<"层次遍历为"<<endl;
CenOrder(Visit,root);
cout<<endl;
}
void Delete()
{
Delete(root);
root=NULL;
cout<<"释放空间完成"<<endl;
}
int CountNode()
{
return CountNode(root);
}
int GetHeight()
{
return GetHeight(root);
}
int GetLeaf()
{
return GetLeaf(root);
}
BTNode<T> * CopyTree()const;
void operator=(const BTree<T>& copyFrom);
private:
BTNode<T>* root;
void PreOrder(void (*Visit)(BTNode<T>*u), BTNode<T>*t);
void InOrder(void (*Visit)(BTNode<T>* u), BTNode<T>*t);
void PostOrder(void (*Visit)(BTNode<T>* u), BTNode<T>*t);
void Change(BTNode<T> *t);
void CenOrder(void (*Visit)(BTNode<T>* u),BTNode<T>* t);
void Delete(BTNode<T>* p);
int CountNode(BTNode<T> *p);
int GetHeight(BTNode<T>* t);
int GetLeaf(BTNode<T> *t);
BTNode<T> * CopyTree(BTNode<T> *t)const;
};
template<class T>
int BTree<T>::GetLeaf(BTNode<T> *t)
{
if(!t)return 0;
int tmp=0;
if(t->lchild!=NULL)
{
tmp+=GetLeaf(t->lchild);
}
if(t->rchild!=NULL)
{
tmp+=GetLeaf(t->rchild);
}
if(t->lchild==NULL&&t->rchild==NULL)
{
return 1;
}
return tmp;
}
template <class T>
int BTree<T>::GetHeight(BTNode<T>* t)
{
if(!t)return 0; //若为空节点,则返回0
if((!t->lchild)&&(!t->rchild)) return 1; //若为叶子节点,则返回1
int lHeight=GetHeight(t->lchild);
int rHeight=GetHeight(t->rchild);
return (lHeight>rHeight?lHeight:rHeight)+1; //若不是叶子节点,则返回左右子树中高度最大的高度+1
}
template <class T>
int BTree<T>::CountNode(BTNode<T> *p)
{
if(p==NULL) return 0;
else return CountNode(p->lchild)+CountNode(p->rchild)+1;
}
template <class T>
void BTree<T>::Delete(BTNode<T>* p)
{
if(p==NULL) return;
if(p->lchild!=NULL)
{
Delete(p->lchild);
}
if(p->rchild!=NULL)
{
Delete(p->rchild);
}
delete p;
}
//判断二叉树是否为空
template<class T>
bool BTree<T>::IsEmpty() const
{
return root==NULL;
}
//求二叉树根结点的值
template <class T>
bool BTree<T>::Root(T &x) const
{
if (root)
{
x=root->element;
return true;
}
else return false;
}
//建造一棵二叉树,T为新生成树的根结点
//left,right为新生成树的左右子树
template <class T>
void BTree<T>::MakeTree(const T &e, BTree<T>& left, BTree<T>& right)
{
if(root||&left==&right) return;
root=new BTNode<T>(e,left.root,right.root);
left.root=right.root=NULL;
cout<<"here in BTree<T>::MakeTree"<<endl;
}
//求二叉树根结点的值,
//left,right为左右两棵子树
//此处应该修改,原树root应该为空
template <class T>
void BTree<T>::BreakTree(T &e,BTree<T>&left, BTree<T>& right)
{
cout<<"here in BTree<T>::BreakTree."<<endl;
if(left.root||right.root||!root||&left==&right) return ;
e=root->element;
left.root=root->lchild;
right.root=root->rchild;
delete root;
root=NULL;
}
template <class T>
void BTree<T>::PreOrder(void (*Visit)(BTNode<T>* u),BTNode<T>* t)
{
if(t)
{
Visit(t);
PreOrder(Visit,t->lchild);
PreOrder(Visit,t->rchild);
}
}
template <class T>
void BTree<T>::InOrder (void (*Visit)(BTNode<T>* u),BTNode<T>* t)
{
if (t)
{
InOrder(Visit,t->lchild);
Visit(t);
InOrder(Visit,t->rchild);
}
}
template <class T>
void BTree<T>::PostOrder(void (*Visit)(BTNode<T>* u),BTNode<T>* t)
{
if (t)
{
PostOrder(Visit,t->lchild);
PostOrder(Visit,t->rchild);
Visit(t);
}
}
/*实现二叉树的按层遍历,用到了一个队列(第三章中的循环队列)
首先将根结点入队列,当对列不为空的时候:取队首元素,输出队首元素,
将队首元素的左右结点入队列,删除队首元素。如此循环直到队列为空。
该程序不是递归算法。
*/
template <class T>
void BTree<T>::CenOrder(void (*Visit)(BTNode<T>* u),BTNode<T>* t)
{
if(t==NULL) return;
queue<BTNode<T>* > s;
s.push(t);
BTNode<T> *p;
while(s.empty()==0)
{
p=s.front();
Visit(p);
if(p->lchild!=NULL)
{
s.push(p->lchild);
}
if(p->rchild!=NULL)
{
s.push(p->rchild);
}
s.pop();
}
}
template <class T>
void BTree<T>::Change(BTNode<T> *t)
{
if(t)
{
Change(t->lchild);
Change(t->rchild);
BTNode<T> *p;
p=t->lchild;
t->lchild=t->rchild;
t->rchild=p;
}
}
template<class T>
BTNode<T> * BTree<T>::CopyTree()const
{
return CopyTree(root);
}
template<class T>
BTNode<T> * BTree<T>::CopyTree(BTNode<T> *t)const
{
if(t==NULL)
return NULL; //若为空树则返回NULL
BTNode<T>* pointer=new BTNode<T>(t->element); //复制当前节点
pointer->lchild=CopyTree(t->lchild);
pointer->rchild=CopyTree(t->rchild);
return pointer;
}
template<class T>
void BTree<T>::operator=(const BTree<T> & copyFrom)
{
this->Delete();
root=copyFrom.CopyTree();
}
head.h
#include <iostream>
using namespace std;
template<class T>class BTree;//Note
template<class T>
class BTNode
{
public:
BTNode(){lchild = rchild = 0;}
BTNode(const T & x){ element = x; lchild = rchild = 0;}
BTNode(const T& x,BTNode<T> *l,BTNode<T> *r)
{
element = x;
lchild = l;
rchild = r;
}
friend class BTree<T>;
friend void Visit(BTNode<T> *);
T element;
private:
BTNode<T> *lchild,*rchild;
};
template<class T>
void Visit(BTNode<T> * p )
{
cout<<p->element<<" ";
}
程序二:哈夫曼编码译码系统的实现
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <string> #include <fstream> using namespace std; template<class T> struct BTNode { BTNode(){value=NULL;lChild=rChild=NULL;} BTNode(const T &x) { element=x; value=NULL; lChild=rChild=NULL; parent=NULL; } BTNode(const T &x,char v) { element=x; value=v; lChild=rChild=NULL; parent=NULL; } BTNode(const T&x,BTNode<T>*l,BTNode<T>*r) { element=x; lChild=l; rChild=r; value=NULL; parent=NULL; } BTNode(const T&x,char v,BTNode<T>*l,BTNode<T>*r) { element=x; lChild=l; rChild=r; value=v; parent=NULL; } T element; BTNode<T> *lChild,*rChild,*parent; char value; int v; vector<int> code; }; template<class T> class PrioQueue { public: PrioQueue(int mSize=20); ~PrioQueue(){delete []q;} bool IsEmpty()const{return n==0;} bool IsFull()const{return n==maxSize;} void Append(const T &x); void Serve(T &x); private: void AdjustDown(int r,int j); void AdjustUp(int j); T *q; int n,maxSize; }; template<class T> PrioQueue<T>::PrioQueue(int mSize) { maxSize=mSize; n=0; q=new T[maxSize]; } template<class T> void PrioQueue<T>::AdjustDown(int r,int j) { int child=2*r+1; T tmp=q[r]; while(child<=j) { if((child<j)&&(q[child]>q[child+1])) child++; if(tmp<=q[child]) break; q[(child-1)/2]=q[child]; child=child*2+1; } q[(child-1)/2]=tmp; } template<class T> void PrioQueue<T>::AdjustUp(int j) { int i=j; T tmp=q[i]; while(i>0&&tmp<q[(i-1)/2]) { q[i]=q[(i-1)/2]; i=(i-1)/2; } q[i]=tmp; } template<class T> void PrioQueue<T>::Append(const T &x) { if(IsFull()) { cout<<"Overflow!"<<endl; return ; } q[n++]=x; AdjustUp(n-1); } template<class T> void PrioQueue<T>::Serve(T &x) { if(IsEmpty()) { cout<<"Underflow!"<<endl; return ; } x=q[0]; q[0]=q[--n]; AdjustDown(0,n-1); } void Visit(BTNode<int>* pointer) { cout<<'('<< "lChild="<<pointer->lChild<<'|'<< "rChild="<<pointer->rChild<<'|'<< "weight="<<pointer->element<<'|'<< "value="<<pointer->value<<'|'<< "parent="<<pointer->parent <<')'<<endl; } template<class T> class BinaryTree { public: BinaryTree(){root=NULL;} ~BinaryTree(){} void MakeTree(const T&x,char value,BinaryTree<T> & left,BinaryTree<T> & right); void PreOrder(void (*Visit)(BTNode<T> *x)); void InOrder(void (*Visit)(BTNode<T> *x)); void PostOrder(void (*Visit)(BTNode<T> *x)); void LevelOrder(); void Clear(); void PreOrder(void (*Visit)(BTNode<T> *x),BTNode<T>*t); void InOrder(void (*Visit)(BTNode<T> *x),BTNode<T>*t); void PostOrder(void (*Visit)(BTNode<T> *x),BTNode<T>*t); void Clear(BTNode<T>**t); void LevelOrder(void (*Visit)(BTNode<T> *x)); protected: BTNode<T>* root; }; template<class T> void BinaryTree<T>::MakeTree(const T&x,char value,BinaryTree<T>&left,BinaryTree<T>&right) { if(root||&left==&right) return; root=new BTNode<T>(x,value,left.root,right.root); if(left.root!=right.root) { left.root->v=0; right.root->v=1; } left.root=right.root=NULL; } template<class T> void BinaryTree<T>::Clear() { Clear(&root); root=NULL; cout<<"清除完成"<<endl; } template<class T> void BinaryTree<T>::Clear(BTNode<T>**t) { if(*t==NULL) return; Clear(&((*t)->lChild)); Clear(&((*t)->rChild)); delete *t; *t=NULL; } template<class T> void BinaryTree<T>::PreOrder(void (*Visit)(BTNode<T> *x)) { cout<<"先序遍历是: "; PreOrder(Visit,root); } template<class T> void BinaryTree<T>::PreOrder(void (*Visit)(BTNode<T> *x),BTNode<T>* t) { if(t) { Visit(t); PreOrder(Visit,t->lChild); PreOrder(Visit,t->rChild); } } template<class T> void BinaryTree<T>::InOrder(void (*Visit)(BTNode<T> *x)) { cout<<"中序遍历是: "; InOrder(Visit,root); } template<class T> void BinaryTree<T>::InOrder(void (*Visit)(BTNode<T> *x),BTNode<T>* t) { if (t) { InOrder(Visit,t->lChild); Visit(t); InOrder(Visit,t->rChild); } } template<class T> void BinaryTree<T>::PostOrder(void (*Visit)(BTNode<T> *x)) { cout<<"后序遍历是: "; PostOrder(Visit,root); } template<class T> void BinaryTree<T>::PostOrder(void (*Visit)(BTNode<T> *x),BTNode<T>* t) { if (t) { PostOrder(Visit,t->lChild); PostOrder(Visit,t->rChild); Visit(t); } } template<class T> void BinaryTree<T>::LevelOrder() { cout<<"层次遍历是 "; LevelOrder(root); } template<class T> void BinaryTree<T>::LevelOrder(void (*Visit)(BTNode<T> *x)) { if(root==NULL) return; queue<BTNode<T>* > s; s.push(root); BTNode<T> *p; while(s.empty()==0) { p=s.front(); Visit(p); if(p->lChild!=NULL) { s.push(p->lChild); } if(p->rChild!=NULL) { s.push(p->rChild); } s.pop(); } } template<class T> class HfmTree:public BinaryTree<T> { public: operator T()const{return weight;} T getW()const {return weight;} void putW(const T &x){weight=x;} void SetNull() {this->root=NULL;} void CreateCode(); void getcode(); BTNode<T>* FindV(char value); void CodeToArticle(); void GetParents(); private: T weight; void CreateCode(BTNode<T>*t); void getcode(BTNode<T>* t); BTNode<T>* FindV(char value,BTNode<T> *t); void CodeToArticle(BTNode<T> *p); void GetParents(BTNode<T> * t); }; template<class T> BTNode<T>* HfmTree<T>::FindV(char value) { return FindV(value,this->root); } template<class T> BTNode<T>* HfmTree<T>::FindV(char value,BTNode<T> *t) { if(!t) return NULL; if(t->value==value) return t; BTNode<T>* p; if(p=FindV(value,t->lChild)) return p; if(p=FindV(value,t->rChild)) return p; return NULL; } template<class T> void HfmTree<T>::GetParents() { if(this->root) GetParents(this->root); } template<class T> void HfmTree<T>::GetParents(BTNode<T> * t) { if(!t) return; if(t->lChild!=NULL) { t->lChild->parent=t; } if(t->rChild!=NULL) { t->rChild->parent=t; } GetParents(t->lChild); GetParents(t->rChild); } template<class T> void HfmTree<T>::CreateCode() { CreateCode(this->root); } template<class T> void HfmTree<T>::CreateCode(BTNode<T>* t) { if(t==NULL) return ; if(t->parent) { for(int i=0;i<t->parent->code.size();i++) { t->code.push_back(t->parent->code[i]); } t->code.push_back(t->v); } CreateCode(t->lChild); CreateCode(t->rChild); } template<class T> void HfmTree<T>::getcode() //E { cout<<"当前编码为:"<<endl; getcode(this->root); } template<class T> void HfmTree<T>::getcode(BTNode<T>* t) { if(t==NULL) return; if((t->lChild==NULL)&&(t->rChild==NULL)) { cout<<t->value<<":"; for(int i=0;i<t->code.size();i++) { cout<<t->code[i]; } cout<<endl; } getcode(t->lChild); getcode(t->rChild); } HfmTree<int> Hfm; int num; int *w; char *s; void ShowMenu() { cout<<endl<<"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Hfm Coding System>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<<endl; cout<<" choose B first!."<<endl; cout<<" 'B'------Build up tree: read character set and frequency of each character, build up hfm tree."<<endl; cout<<" 'T'------Trace the tree: PreOrder and InOrder the bintree."<<endl; cout<<" 'E'------Generate code: According to the builded up hfm tree, generate the codes for all character."<<endl; cout<<" 'C'------Encode: Input arbitary string formed by characters which have been generated code, utilize the codes to ecode and print the result of encoding."<<endl; cout<<" 'D'------Translate: read codefile.txt, utilize the exisiting hfm tree to translate code and restore code into hardware file result.txt."<<endl; cout<<" 'P'------Print: Print the contents of file: textfile.txt, codefile.txt, result.txt on the screen."<<endl; cout<<" 'X'------Exit: Exit this system."<<endl; cout<<" '-'------Delete: Delete character set, character frequencies, codes and HfmTree if they are exist."<<endl<<endl; cout<<"\n input your choice :"<<endl; } template<class T> HfmTree<T> CreateHfmTree(T w[],char s[],int n) //构造哈夫曼树 { int i; PrioQueue<HfmTree<T> > pq(n); HfmTree<T> x, y, z, zero; for(i = 0; i < n; i++) { z.MakeTree(w[i], s[i], x ,y); z.putW(w[i]); pq.Append(z); z.SetNull(); } for(i = 1; i < n; i++) { pq.Serve(x); pq.Serve(y); z.MakeTree(x.getW() + y.getW(),'0', x, y); z.putW(x.getW() + y.getW()); pq.Append(z); z.SetNull(); } pq.Serve(z); return z; } void buildtree() { char c; int i=0; cout<<"Please input the number of elementary code: "; cin>>num; cout<<"Allocating the memory..."<<endl; w=new int[num+1]; cout<<"Allocating the complete."<<endl; s=new char[num+1]; cout<<"Please input all the elementary codes:(form:'(char,char...char,char)')"<<endl; while(i<num) { cin>>c; if((c=='(')||(c==')')||(c==','))continue; s[i++]=c; } cin>>c; //接收')' cout<<"Elementary code input complete. Codes you input are:"<<endl; for(i=0;i<num;i++) cout<<s[i]<<" "; cout<<endl<<"Please input all the Frenquencies: "; for(i=0;i<num;i++) cin>>w[i]; cout<<"Frenquencies input complete. Frenquencies you input are:"<<endl; for(i=0;i<num;i++) cout<<w[i]<<" "; cout<<endl; Hfm=CreateHfmTree(w,s,num); Hfm.GetParents(); Hfm.CreateCode(); cout<<"Create Hfm tree complete"<<endl; } void BianLi() { Hfm.PreOrder(Visit); Hfm.InOrder(Visit); Hfm.PostOrder(Visit); Hfm.LevelOrder(Visit); } void clear() { if(s) { cout<<"Deleting character set..."<<endl; delete []s; s=NULL; } if(w) { cout<<"Deleting character frequencies..."<<endl; delete []w; w=NULL; } } void ArticleToCode() //C { ofstream foutt("textfile.txt"); if(!foutt) { cout<<"Cannot open textfile.txt!"<<endl; return ; } ofstream foutc("codefile.txt"); if(!foutc) { cout<<"Cannot open codefile.txt!"<<endl; return ; } cout<<"Please input the article that you want to code: (end with Enter)"<<endl; getchar(); string ss; getline(cin,ss); foutt<<ss; for(int i=0;i<ss.size();i++) { BTNode<int> *p=Hfm.FindV(ss[i]); if(p==NULL) { printf("未找到字符 %c \n",ss[i]); continue; } for(int j=0;j<p->code.size();j++) { printf("%d",p->code[j]); char cc=p->code[j]+'0'; foutc<<cc; } } cout<<endl<<endl; cout<<"Encoding complete."<<endl<<endl; foutt.close(); foutc.close(); } template<class T> void HfmTree<T>::CodeToArticle() { CodeToArticle(this->root); } template<class T> void HfmTree<T>::CodeToArticle(BTNode<T>* t) { ofstream foutr("resultfile.txt"); if(!foutr) { cout<<"Cannot open resultfile.txt!"<<endl; return ; } char c; ifstream foutc("codefile.txt"); if(!foutc) { cout<<"Cannot open codefile.txt!"<<endl; return ; } cout<<"请输入选项:"<<endl<<"1. 输入01代码进行译码"<<endl<<"2. 对codefile.txt文件中01代码进行译码"<<endl; int choice; string ccs; cin>>choice; if(choice==2) { foutc>>ccs; } else if(choice==1) { cout<<"输入代码,无空格,回车结束"<<endl; string cc; getchar(); cin>>ccs; } else { return; } int i=0; while(i<ccs.size()) { BTNode<int> *p=t; while(p->lChild!=NULL||p->rChild!=NULL) { if(ccs[i]=='0') { p=p->lChild; } else { p=p->rChild; } i++; } printf("%c ",p->value); foutr<<(p->value); } cout<<endl<<endl; } void Print() { ifstream foutt("textfile.txt"); if(!foutt) { cout<<"Cannot open textfile.txt!"<<endl; return ; } cout<<endl<<"----------------------textfile.txt----------------------"<<endl; string ss; while(foutt>>ss) { cout<<ss<<" "; } cout<<endl<<"--------------------------------------------------------"<<endl; foutt.close(); ifstream foutc("codefile.txt"); if(!foutc) { cout<<"Cannot open codefile.txt!"<<endl; return ; } cout<<endl<<"----------------------codefile.txt----------------------"<<endl; while(foutc>>ss) { cout<<ss<<" "; } cout<<endl<<"--------------------------------------------------------"<<endl; foutc.close(); ifstream foutr("resultfile.txt"); if(!foutr) { cout<<"Cannot open resultfile.txt!"<<endl; return ; } cout<<endl<<"---------------------resultfile.txt---------------------"<<endl; while(foutr>>ss) { cout<<ss<<" "; } cout<<endl<<"--------------------------------------------------------"<<endl; foutr.close(); } int main() { // freopen("in.txt","r",stdin); char ch; ShowMenu(); cin >> ch; while(ch != 'X'&&ch!='x') { switch(ch) { case 'B': case 'b': buildtree(); break; case 'T': case 't': BianLi(); break; case 'E': case 'e': Hfm.getcode(); break; case 'C': case 'c': ArticleToCode(); break; case 'D': case 'd': Hfm.CodeToArticle(); break; case 'P': case 'p': Print(); case 'X': case 'x': return 0; case '-': Hfm.Clear(); } system("PAUSE"); system("CLS"); ShowMenu(); cin >> ch; } return 0; }
相关文章推荐
- 二叉树基本操作实现(二叉树的顺序存储)
- C语言实现二叉树的基本操作---创建、遍历、求深度、求叶子结点
- 二叉树基本操作的递归实现(二叉树建立,先序,中序,后序,深度的递归遍历。广度优先,高度优先的非递归遍历)
- 使用HDFS API实现hadoop HDFS文件系统的基本操作
- 数据结构:二叉树的基本操作(JAVA实现)
- 二叉树基本操作实现(二叉树的链式存储)
- 南邮数据结构实验2 (1)二叉树基本操作
- Redis缓存系统-Java-Jedis操作Redis,基本操作以及 实现对象保存
- c++学习笔记—二叉树基本操作的实现
- 二叉树基本操作的程序实现
- 八.二叉树各种操作的C语言实现 树的一些基本的操作,包括,树的建立,树的深度,
- 二叉树的建立(非递归建立与定义建立)与基本操作(广度和深度遍历,求叶子树高)实现
- javascript实现数据结构: 树和二叉树,二叉树的遍历和基本操作
- 【 数据结构】实现二叉树以及其基本操作
- C实现二叉树BTree基本操作
- 数据结构.二叉树的基本操作(C语言实现)
- 二叉树基本操作--java实现
- 二叉树基本操作的程序实现
- 二叉树基本操作java实现及遍历浅析
- 二叉树基本操作的程序实现