目的:创建一棵二叉树,实现先序、中序和后序遍历一棵二叉树,
计算二叉树结点个数等操作。
哈夫曼编码/译码系统。
要求:
能成功演示二叉树的有关运算,
运算完毕后能成功释放二叉树所有结点占用的系统内存。
程序一:二叉树的创建以及基本运算
main.cpp#include"BTree.h"
#include
int main()
{
BTree 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镜面转换后"<
#include "head.h"
#include
#include
#include
template
class BTree
{
public:
BTree(){root=NULL;}
~BTree()
{
Delete();
}
bool IsEmpty()const;
bool Root(T &x)const;
void MakeTree(const T &e ,BTree& left, BTree& right);
void BreakTree(T &e ,BTree& left,BTree& right);
void PreOrder(void (*Visit)(BTNode* u))
{
cout<<"先序遍历为"<* u))
{
cout<<"中序遍历为"<* u))
{
cout<<"后序遍历为"<* u))
{
cout<<"层次遍历为"< * CopyTree()const;
void operator=(const BTree& copyFrom);
private:
BTNode* root;
void PreOrder(void (*Visit)(BTNode*u), BTNode*t);
void InOrder(void (*Visit)(BTNode* u), BTNode*t);
void PostOrder(void (*Visit)(BTNode* u), BTNode*t);
void Change(BTNode *t);
void CenOrder(void (*Visit)(BTNode* u),BTNode* t);
void Delete(BTNode* p);
int CountNode(BTNode *p);
int GetHeight(BTNode* t);
int GetLeaf(BTNode *t);
BTNode * CopyTree(BTNode *t)const;
};
template
int BTree::GetLeaf(BTNode *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
int BTree::GetHeight(BTNode* 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
int BTree::CountNode(BTNode *p)
{
if(p==NULL) return 0;
else return CountNode(p->lchild)+CountNode(p->rchild)+1;
}
template
void BTree::Delete(BTNode* p)
{
if(p==NULL) return;
if(p->lchild!=NULL)
{
Delete(p->lchild);
}
if(p->rchild!=NULL)
{
Delete(p->rchild);
}
delete p;
}
//判断二叉树是否为空
template
bool BTree::IsEmpty() const
{
return root==NULL;
}
//求二叉树根结点的值
template
bool BTree::Root(T &x) const
{
if (root)
{
x=root->element;
return true;
}
else return false;
}
//建造一棵二叉树,T为新生成树的根结点
//left,right为新生成树的左右子树
template
void BTree::MakeTree(const T &e, BTree& left, BTree& right)
{
if(root||&left==&right) return;
root=new BTNode(e,left.root,right.root);
left.root=right.root=NULL;
cout<<"here in BTree::MakeTree"<
void BTree::BreakTree(T &e,BTree&left, BTree& right)
{
cout<<"here in BTree::BreakTree."<element;
left.root=root->lchild;
right.root=root->rchild;
delete root;
root=NULL;
}
template
void BTree::PreOrder(void (*Visit)(BTNode* u),BTNode* t)
{
if(t)
{
Visit(t);
PreOrder(Visit,t->lchild);
PreOrder(Visit,t->rchild);
}
}
template
void BTree::InOrder (void (*Visit)(BTNode* u),BTNode* t)
{
if (t)
{
InOrder(Visit,t->lchild);
Visit(t);
InOrder(Visit,t->rchild);
}
}
template
void BTree::PostOrder(void (*Visit)(BTNode* u),BTNode* t)
{
if (t)
{
PostOrder(Visit,t->lchild);
PostOrder(Visit,t->rchild);
Visit(t);
}
}
/*实现二叉树的按层遍历,用到了一个队列(第三章中的循环队列)
首先将根结点入队列,当对列不为空的时候:取队首元素,输出队首元素,
将队首元素的左右结点入队列,删除队首元素。如此循环直到队列为空。
该程序不是递归算法。
*/
template
void BTree::CenOrder(void (*Visit)(BTNode* u),BTNode* t)
{
if(t==NULL) return;
queue* > s;
s.push(t);
BTNode *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
void BTree::Change(BTNode *t)
{
if(t)
{
Change(t->lchild);
Change(t->rchild);
BTNode *p;
p=t->lchild;
t->lchild=t->rchild;
t->rchild=p;
}
}
template
BTNode * BTree::CopyTree()const
{
return CopyTree(root);
}
template
BTNode * BTree::CopyTree(BTNode *t)const
{
if(t==NULL)
return NULL; //若为空树则返回NULL
BTNode* pointer=new BTNode(t->element); //复制当前节点
pointer->lchild=CopyTree(t->lchild);
pointer->rchild=CopyTree(t->rchild);
return pointer;
}
template
void BTree::operator=(const BTree & copyFrom)
{
this->Delete();
root=copyFrom.CopyTree();
}
#include
using namespace std;
templateclass BTree;//Note
template
class BTNode
{
public:
BTNode(){lchild = rchild = 0;}
BTNode(const T & x){ element = x; lchild = rchild = 0;}
BTNode(const T& x,BTNode *l,BTNode *r)
{
element = x;
lchild = l;
rchild = r;
}
friend class BTree;
friend void Visit(BTNode *);
T element;
private:
BTNode *lchild,*rchild;
};
template
void Visit(BTNode * p )
{
cout<element<<" ";
}
程序二:哈夫曼编码译码系统的实现
#include
#include
#include
#include
#include
#include
#include
using namespace std;
template
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*l,BTNode*r)
{
element=x;
lChild=l;
rChild=r;
value=NULL;
parent=NULL;
}
BTNode(const T&x,char v,BTNode*l,BTNode*r)
{
element=x;
lChild=l;
rChild=r;
value=v;
parent=NULL;
}
T element;
BTNode *lChild,*rChild,*parent;
char value;
int v;
vector code;
};
template
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
PrioQueue::PrioQueue(int mSize)
{
maxSize=mSize;
n=0;
q=new T[maxSize];
}
template
void PrioQueue::AdjustDown(int r,int j)
{
int child=2*r+1;
T tmp=q[r];
while(child<=j)
{
if((childq[child+1])) child++;
if(tmp<=q[child]) break;
q[(child-1)/2]=q[child];
child=child*2+1;
}
q[(child-1)/2]=tmp;
}
template
void PrioQueue::AdjustUp(int j)
{
int i=j;
T tmp=q[i];
while(i>0&&tmp
void PrioQueue::Append(const T &x)
{
if(IsFull())
{
cout<<"Overflow!"<
void PrioQueue::Serve(T &x)
{
if(IsEmpty())
{
cout<<"Underflow!"<* pointer)
{
cout<<'('<<
"lChild="<lChild<<'|'<<
"rChild="<rChild<<'|'<<
"weight="<element<<'|'<<
"value="<value<<'|'<<
"parent="<parent
<<')'<
class BinaryTree
{
public:
BinaryTree(){root=NULL;}
~BinaryTree(){}
void MakeTree(const T&x,char value,BinaryTree & left,BinaryTree & right);
void PreOrder(void (*Visit)(BTNode *x));
void InOrder(void (*Visit)(BTNode *x));
void PostOrder(void (*Visit)(BTNode *x));
void LevelOrder();
void Clear();
void PreOrder(void (*Visit)(BTNode *x),BTNode*t);
void InOrder(void (*Visit)(BTNode *x),BTNode*t);
void PostOrder(void (*Visit)(BTNode *x),BTNode*t);
void Clear(BTNode**t);
void LevelOrder(void (*Visit)(BTNode *x));
protected:
BTNode* root;
};
template
void BinaryTree::MakeTree(const T&x,char value,BinaryTree&left,BinaryTree&right)
{
if(root||&left==&right) return;
root=new BTNode(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
void BinaryTree::Clear()
{
Clear(&root);
root=NULL;
cout<<"清除完成"<
void BinaryTree::Clear(BTNode**t)
{
if(*t==NULL) return;
Clear(&((*t)->lChild));
Clear(&((*t)->rChild));
delete *t;
*t=NULL;
}
template
void BinaryTree::PreOrder(void (*Visit)(BTNode *x))
{
cout<<"先序遍历是: ";
PreOrder(Visit,root);
}
template
void BinaryTree::PreOrder(void (*Visit)(BTNode *x),BTNode* t)
{
if(t)
{
Visit(t);
PreOrder(Visit,t->lChild);
PreOrder(Visit,t->rChild);
}
}
template
void BinaryTree::InOrder(void (*Visit)(BTNode *x))
{
cout<<"中序遍历是: ";
InOrder(Visit,root);
}
template
void BinaryTree::InOrder(void (*Visit)(BTNode *x),BTNode* t)
{
if (t)
{
InOrder(Visit,t->lChild);
Visit(t);
InOrder(Visit,t->rChild);
}
}
template
void BinaryTree::PostOrder(void (*Visit)(BTNode *x))
{
cout<<"后序遍历是: ";
PostOrder(Visit,root);
}
template
void BinaryTree::PostOrder(void (*Visit)(BTNode *x),BTNode* t)
{
if (t)
{
PostOrder(Visit,t->lChild);
PostOrder(Visit,t->rChild);
Visit(t);
}
}
template
void BinaryTree::LevelOrder()
{
cout<<"层次遍历是 ";
LevelOrder(root);
}
template
void BinaryTree::LevelOrder(void (*Visit)(BTNode *x))
{
if(root==NULL) return;
queue* > s;
s.push(root);
BTNode *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 HfmTree:public BinaryTree
{
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* FindV(char value);
void CodeToArticle();
void GetParents();
private:
T weight;
void CreateCode(BTNode*t);
void getcode(BTNode* t);
BTNode* FindV(char value,BTNode *t);
void CodeToArticle(BTNode *p);
void GetParents(BTNode * t);
};
template
BTNode* HfmTree::FindV(char value)
{
return FindV(value,this->root);
}
template
BTNode* HfmTree::FindV(char value,BTNode *t)
{
if(!t) return NULL;
if(t->value==value) return t;
BTNode* p;
if(p=FindV(value,t->lChild)) return p;
if(p=FindV(value,t->rChild)) return p;
return NULL;
}
template
void HfmTree::GetParents()
{
if(this->root)
GetParents(this->root);
}
template
void HfmTree::GetParents(BTNode * 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
void HfmTree::CreateCode()
{
CreateCode(this->root);
}
template
void HfmTree::CreateCode(BTNode* t)
{
if(t==NULL) return ;
if(t->parent)
{
for(int i=0;iparent->code.size();i++)
{
t->code.push_back(t->parent->code[i]);
}
t->code.push_back(t->v);
}
CreateCode(t->lChild);
CreateCode(t->rChild);
}
template
void HfmTree::getcode() //E
{
cout<<"当前编码为:"<root);
}
template
void HfmTree::getcode(BTNode* t)
{
if(t==NULL) return;
if((t->lChild==NULL)&&(t->rChild==NULL))
{
cout<value<<":";
for(int i=0;icode.size();i++)
{
cout<code[i];
}
cout<lChild);
getcode(t->rChild);
}
HfmTree Hfm;
int num;
int *w;
char *s;
void ShowMenu()
{
cout<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<
HfmTree CreateHfmTree(T w[],char s[],int n) //构造哈夫曼树
{
int i;
PrioQueue > pq(n);
HfmTree 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..."<>c;
if((c=='(')||(c==')')||(c==','))continue;
s[i++]=c;
}
cin>>c; //接收')'
cout<<"Elementary code input complete. Codes you input are:"<>w[i];
cout<<"Frenquencies input complete. Frenquencies you input are:"< *p=Hfm.FindV(ss[i]);
if(p==NULL)
{
printf("未找到字符 %c \n",ss[i]);
continue;
}
for(int j=0;jcode.size();j++)
{
printf("%d",p->code[j]);
char cc=p->code[j]+'0';
foutc<
void HfmTree::CodeToArticle()
{
CodeToArticle(this->root);
}
template
void HfmTree::CodeToArticle(BTNode* t)
{
ofstream foutr("resultfile.txt");
if(!foutr)
{
cout<<"Cannot open resultfile.txt!"<>choice;
if(choice==2)
{
foutc>>ccs;
}
else if(choice==1)
{
cout<<"输入代码,无空格,回车结束"<>ccs;
}
else
{
return;
}
int i=0;
while(i *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<>ss)
{
cout<>ss)
{
cout<>ss)
{
cout<> 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;
}