南邮数据结构实验二---二叉树的基本操作及哈夫曼编码译码系统的实现

目的:创建一棵二叉树,实现先序、中序和后序遍历一棵二叉树,

计算二叉树结点个数等操作。

哈夫曼编码/译码系统。

要求:

能成功演示二叉树的有关运算,

运算完毕后能成功释放二叉树所有结点占用的系统内存。


程序一:二叉树的创建以及基本运算

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镜面转换后"<

BTree.cpp

#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();
}


head.h

#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;
}










你可能感兴趣的:(作业)