二叉树基本操作与哈夫曼编码译码系统实现.docx
《二叉树基本操作与哈夫曼编码译码系统实现.docx》由会员分享,可在线阅读,更多相关《二叉树基本操作与哈夫曼编码译码系统实现.docx(19页珍藏版)》请在冰豆网上搜索。
二叉树基本操作与哈夫曼编码译码系统实现
实验报告
(/学年第一学期)
课程名称
数据结构A
实验名称
二叉树的基本操作及哈夫曼编码译码系统的实现
实验时间
年
月
日
指导单位
指导教师
学生姓名
班级学号
学院(系)
专业
实验报告
实验名称
二叉树的基本操作及哈夫曼编码译码系统的实现
指导教师
实验类型
上机
实验学时
实验时间
一、实验目的和要求
实验目的:
1、掌握二叉链表上实现二叉树基本运算的方法。
2、学会设计基于遍历的求解二叉树应用问题的递归算法。
3、理解哈夫曼树的构造算法,学会设计哈夫曼编码和译码系统。
内容和要求:
1、在二叉链表上实现二叉树运算
设计递归算法,实现下列算法:
删除一棵二叉树,求一棵二叉树的高度,求一棵二叉树中叶子结点的个数,复制一棵二叉树,交换一颗二叉树的左右子树。
设计算法,按自上到下,自左向右的次序,即按层次遍历一颗二叉树。
设计main函数,测试上述每个运算。
2、哈夫曼编码和译码系统
设计的系统重复显示以下菜单项:
建树、遍历、生成编码、编码、译码、打印、退出并且实现这些功能。
二、实验环境(实验设备)
硬件:
PC
软件:
Code:
:
Blocks(C++)
三、实验原理及内容
1、线性表的基本运算
(1)核心算法
删除一颗二叉树:
思路:
将一颗二叉树拆分成三部分,执行语句“deleteroot;root=NULL”,将原二叉树的根结点回收。
代码:
template
voidBinaryTree:
:
BreakTree(T&x,BinaryTree&left,BinaryTree&right)
{
if(!
root||&left==&right||left.root||right.root)
{
return;
}
x=root->element;
left.root=root->lChild;
right.root=root->rChild;
deleteroot;
root=NULL;
}
求一棵二叉树的高度:
思路:
递归搜索二叉树,不断返回高度。
代码:
template
intBinaryTree:
:
High()
{
inth=High2(root);
returnh;
}
template
intBinaryTree:
:
High2(BTNode*p)
{
if(!
p)
{
return0;
}
inth1,h2;
h1=High2(p->lChild);
h2=High2(p->rChild);
if(h1>h2)
{
returnh1+1;
}
else
{
returnh2+1;
}
}
求一棵二叉树中叶子结点的个数:
思路:
递归搜索二叉树的叶子结点,不断累加。
代码:
template
intBinaryTree:
:
Leaves()
{
intnumber=0;
Leaf(root,number);
returnnumber;
}
template
voidBinaryTree:
:
Leaf(BTNode*p,int&a)
{
if(p)
{
if(p->lChild==0&&p->rChild==0)
{
a++;
}
Leaf(p->lChild,a);
Leaf(p->rChild,a);
}
}
复制一棵二叉树:
思路:
用q指针指向复制的二叉树的根结点,递归调用Copy(),不断复制左子树和右子树。
代码:
template
voidBinaryTree:
:
Copy(BinaryTree&p)
{
BTNode*q=Copy(root);
p.root=q;
}
template
BTNode*BinaryTree:
:
Copy(BTNode*t)
{
if(!
t)
{
returnNULL;
}
BTNode*q=newBTNode(t->element);
q->lChild=Copy(t->lChild);
q->rChild=Copy(t->rChild);
returnq;
}
交换一颗二叉树的左右子树:
思路:
递归调用Change(),不断交换左、右子树。
代码:
template
voidBinaryTree:
:
Exchange()
{
Change(root);
}
template
voidBinaryTree:
:
Change(BTNode*t)
{
if(t)
{
BTNode*temp=t->lChild;
t->lChild=t->rChild;
t->rChild=temp;
Change(t->lChild);
Change(t->rChild);
}
}
按自上到下,自左向右的次序的层次遍历:
思路:
利用队列作为辅助数据结构,队列的元素类型是指向二叉树中结点的指针类型,首先让根结点入队,接着做一个循环:
每当一个元素出队,则它的左右子树依次入队。
代码:
template
classSeqQueue
{
private:
intfront,rear;
intmaxSize;
T*q;
public:
SeqQueue(intm);
~SeqQueue(){delete[]q;}
boolEnQueue(constTx);
boolDeQueue();
boolFront(T&x)const;
boolIsEmpty(){returnfront==rear;};
boolIsFull(){return(rear+1)%maxSize==front;};
voidClear(){front=rear=0;}
};
template
SeqQueue:
:
SeqQueue(intm)
{
maxSize=m;
q=newT[m];
front=rear=0;
}
template
boolSeqQueue:
:
Front(T&x)const
{
x=q[(front+1)%maxSize];
returntrue;
}
template
boolSeqQueue:
:
EnQueue(constTx)
{
if(IsFull())
{
cout<<"full"<returnfalse;
}
q[(rear=(rear+1)%maxSize)]=x;
returntrue;
}
template
boolSeqQueue:
:
DeQueue()
{
if(IsEmpty())
{
cout<<"UnderFlow"<returnfalse;
}
front=(front+1)%maxSize;
returntrue;
}
template
voidBinaryTree:
:
LayerOrder()
{
if(root==0)
{
cout<<"Thistreeisempty!
"<return;
}
BTNode*p=root;
BTNodet;
SeqQueue>q(30);
q.EnQueue(*p);
while(!
q.IsEmpty())
{
q.Front(t);
Visit(t.element);
if(t.lChild)
{
q.EnQueue(*t.lChild);
}
if(t.rChild)
{
q.EnQueue(*t.rChild);
}
q.DeQueue();
}
}
(2)程序流程图
(3)完整代码:
#include
usingnamespacestd;
template
classSeqQueue
{
private:
intfront,rear;
intmaxSize;
T*q;
public:
SeqQueue(intm);
~SeqQueue(){delete[]q;}
boolEnQueue(constTx);
boolDeQueue();
boolFront(T&x)const;
boolIsEmpty(){returnfront==rear;};
boolIsFull(){return(rear+1)%maxSize==front;};
voidClear(){front=rear=0;}
};
template
SeqQueue:
:
SeqQueue(intm)
{
maxSize=m;
q=newT[m];
front=rear=0;
}
template
boolSeqQueue:
:
Front(T&x)const
{
x=q[(front+1)%maxSize];
returntrue;
}
template
boolSeqQueue:
:
EnQueue(constTx)
{
if(IsFull())
{
cout<<"full"<returnfalse;
}
q[(rear=(rear+1)%maxSize)]=x;
returntrue;
}
template
boolSeqQueue:
:
DeQueue()
{
if(IsEmpty())
{
cout<<"UnderFlow"<returnfalse;
}
front=(front+1)%maxSize;
returntrue;
}
template
structBTNode
{
BTNode(){lChild=rChild=NULL;}
BTNode(constT&x)
{
element=x;
lChild=rChild=NULL;
}
BTNode(constT&x,BTNode*l,BTNode*r)
{
element=x;
lChild=l;
rChild=r;
}
Telement;
BTNode*lChild,*rChild;
};
template
classBinaryTree
{
public:
BinaryTree(){root=NULL;}
~BinaryTree();
boolIsEmpty()const;//判断二叉树是否为空
voidClear();//释放二叉链表中的所有节点
boolRoot(T&x)const;//获取根的元素
voidMakeTree(constT&x,BinaryTree&left,BinaryTree&right);//创建二叉树
voidBreakTree(T&x,BinaryTree&left,BinaryTree&right);//删除二叉树
voidPreOrder(void(*Visit)(T&x));//先序遍历
voidInOrder(void(*Visit)(T&x));//中序遍历
voidPostOrder(void(*Visit)(T&x));//后序遍历
voidLayerOrder();//自上到下、从左到右的层次遍历
intHigh();//求二叉树的高度
intLeaves();//求二叉树中叶子结点的数目
voidExchange();//交换二叉树的左右子数
voidCopy(BinaryTree&p);//二叉树的复制(复制给p)
protected:
BTNode*root;
private:
voidClear(BTNode*&t);
voidPreOrder(void(*Visit)(T&x),BTNode*t);
voidInOrder(void(*Visit)(T&x),BTNode*t);
voidPostOrder(void(*Visit)(T&x),BTNode*t);
intHigh2(BTNode*p);
voidLeaf(BTNode*p,int&a);
BTNode*Copy(BTNode*t);
voidChange(BTNode*t);
};
template
boolBinaryTree:
:
Root(T&x)const
{
if(root)
{
x=root->element;
returntrue;
}
else
{
returnfalse;
}
}
template
voidBinaryTree:
:
MakeTree(constT&x,BinaryTree&left,BinaryTree&right)
{
if(root||&left==&right)
{
return;
}
root=newBTNode(x,left.root,right.root);
left.root=right.root=NULL;
}
template
voidBinaryTree:
:
BreakTree(T&x,BinaryTree&left,BinaryTree&right)
{
if(!
root||&left==&right||left.root||right.root)
{
return;
}
x=root->element;
left.root=root->lChild;
right.root=root->rChild;
deleteroot;
root=NULL;
}
template
voidVisit(T&x)
{
cout<}
template
voidBinaryTree:
:
PreOrder(void(*Visit)(T&x))
{
PreOrder(Visit,root);
}
template
voidBinaryTree:
:
PreOrder(void(*Visit)(T&x),BTNode*t)
{
if(t)
{
Visit(t->element);
PreOrder(Visit,t->lChild);
PreOrder(Visit,t->rChild);
}
}
template
voidBinaryTree:
:
InOrder(void(*Visit)(T&x))
{
InOrder(Visit,root);
}
template
voidBinaryTree:
:
InOrder(void(*Visit)(T&x),BTNode*t)
{
if(t)
{
InOrder(Visit,t->lChild);
Visit(t->element);
InOrder(Visit,t->rChild);
}
}
template
voidBinaryTree:
:
PostOrder(void(*Visit)(T&x))
{
PostOrder(Visit,root);
}
template
voidBinaryTree:
:
PostOrder(void(*Visit)(T&x),BTNode*t)
{
if(t)
{
PostOrder(Visit,t->lChild);
PostOrder(Visit,t->rChild);
Visit(t->element);
}
}
template
intBinaryTree:
:
High()
{
inth=High2(root);
returnh;
}
template
intBinaryTree:
:
High2(BTNode*p)
{
if(!
p)
{
return0;
}
inth1,h2;
h1=High2(p->lChild);
h2=High2(p->rChild);
if(h1>h2)
{
returnh1+1;
}
else
{
returnh2+1;
}
}
template
intBinaryTree:
:
Leaves()
{
intnumber=0;
Leaf(root,number);
returnnumber;
}
template
voidBinaryTree:
:
Leaf(BTNode*p,int&a)
{
if(p)
{
if(p->lChild==0&&p->rChild==0)
{
a++;
}
Leaf(p->lChild,a);
Leaf(p->rChild,a);
}
}
template
voidBinaryTree:
:
Copy(BinaryTree&p)
{
BTNode*q=Copy(root);
p.root=q;
}
template
BTNode*BinaryTree:
:
Copy(BTNode*t)
{
if(!
t)
{
returnNULL;
}
BTNode*q=newBTNode(t->element);
q->lChild=Copy(t->lChild);
q->rChild=Copy(t->rChild);
returnq;
}
template
voidBinaryTree:
:
Exchange()
{
Change(root);
}
template
voidBinaryTree:
:
Change(BTNode*t)
{
if(t)
{