实验三二叉树资料.docx

上传人:b****5 文档编号:11543813 上传时间:2023-03-19 格式:DOCX 页数:20 大小:74.34KB
下载 相关 举报
实验三二叉树资料.docx_第1页
第1页 / 共20页
实验三二叉树资料.docx_第2页
第2页 / 共20页
实验三二叉树资料.docx_第3页
第3页 / 共20页
实验三二叉树资料.docx_第4页
第4页 / 共20页
实验三二叉树资料.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

实验三二叉树资料.docx

《实验三二叉树资料.docx》由会员分享,可在线阅读,更多相关《实验三二叉树资料.docx(20页珍藏版)》请在冰豆网上搜索。

实验三二叉树资料.docx

实验三二叉树资料

南昌大学实验报告

---(3)二叉树

学生姓名:

罗明学号:

6100411055专业班级:

计算机111班

实验类型:

■验证□综合□设计□创新实验日期:

2013/5/2实验成绩:

一、实验目的

1.熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题

2.掌握二叉树的基本的存储结构,以及各种操作的算法实现(如建立、遍历)以及应用

3.注意递归算法和非递归算法的设计以及赫夫曼树的应用

二、实验内容

1.按先序次序输入二叉树中结点的值,建立一棵以二叉链表作存储结构的二叉树

2.按先序、中序、后序顺序分别遍历这棵二叉树。

注意,用递归的方法实现先序遍历,用非递归的方法实现中序和后序遍历

3.编写一个求二叉树叶子结点数和二叉树的深度的算法。

4.实现二叉树的线索化

5.构建赫夫曼树,实现赫夫曼编码

三、实验要求

实现二叉树的初始化,并设计出基本操作的算法

四、实验环境

PC微机 

Windows 操作系统 

VisualC++6.0程序集成环境

五、程序代码

1.二叉树的存储结构及遍历二叉树

//-------函数结果状态代码----------

//common.h

#defineTRUE1

#defineFALSE0

#defineOK1

#defineERROR0

#defineINFEASIBLE-1

#defineOVERFLOW-2

typedefintStatus;

//-------二叉树的二叉链表存储结构---------

//BiTree.h

typedefstructBiTNode{

TElemTypedata;

structBiTNode*lchild;//左孩子指针

structBiTNode*rchild;//右孩子指针

}BiTNode,*BiTree;

//-------栈的链式存储结构---------

//LinkStack.h

#defineSTACK_INIT_SIZE20//存储空间初始分配量

#defineSTACKINCREMENT2//存储空间分配增量

typedefstructnode{

SElemTypedata;

structnode*next;

}LinkStack;//链式栈的结构体定义

//-------基本操作的函数原型说明--------

//关于树的

intPreCreateBiTree(BiTree&T);

StatusVISIT(TElemTypee);

StatusPreOrderTraverse(BiTreeT,Status(*visit)(TElemTypee));

StatusInOrderTraverse(BiTreeT,Status(*visit)(TElemTypee));

voidMidVisit(BiTree&T);

voidPostOrderTraverse(BiTreeT,Status(*visit)(TElemTypee));

voidPostOrder(BiTNode*T,Status(*visit)(TElemTypee));

StatusCountLeaf(BiTreeT);

intdeep(BiTreeT);

//关于栈的

StatusInitStack(LinkStack**S);

StatusPush(LinkStack*S,SElemTypex);

StatusPop(LinkStack*S,SElemType&e);

StatusStackEmpty(LinkStack*S);

StatusGetTop(LinkStack*S,SElemType&e);

//--------基本操作的实现-----------

//bitree.cpp

#include

#include

#include

#include"common.h"

typedefcharTElemType;

#include"BiTree.h"

typedefBiTreeSElemType;

#include"LinkStack.h"

intn=0;

//构造而二叉链表表示的二叉树

//插入元素,按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树

intPreCreateBiTree(BiTree&T)//递归先序建立{

chare;

scanf("%c",&e);

if(e==''){

T=NULL;

return1;

}

T=(BiTree)malloc(sizeof(BiTNode));

if(!

T)

exit(OVERFLOW);

T->data=e;//生成根结点

PreCreateBiTree(T->lchild);//构造左子树

PreCreateBiTree(T->rchild);//构造右子树

returnOK;

}

//访问树中元素

StatusVISIT(TElemTypee){

printf("%c",e);

returnOK;

}

//采用递归先序遍历二叉树

StatusPreOrderTraverse(BiTreeT,Status(*visit)(TElemTypee)){

if(T){

if((*visit)(T->data))

if(PreOrderTraverse(T->lchild,VISIT))

if(PreOrderTraverse(T->rchild,VISIT))returnOK;

returnERROR;

}

else

returnOK;

}

//采用中序非递归遍历二叉树

StatusInOrderTraverse(BiTreeT,Status(*visit)(TElemTypee)){

LinkStack*S;

BiTreep;

InitStack(&S);Push(S,T);//根指针进栈

while(!

StackEmpty(S)){

while(GetTop(S,p)&&p)

Push(S,p->lchild);//向左走到尽头

Pop(S,p);

if(!

StackEmpty(S))

{//访问节点,向右一步

Pop(S,p);

if(!

VISIT(p->data))

returnERROR;

Push(S,p->rchild);

}

}

returnOK;

}

//网上查的

voidMidVisit(BiTree&T)//递归中序遍历{

if(!

T)

return;

MidVisit(T->lchild);

printf("%c",T->data);

MidVisit(T->rchild);

}

//采用递归后序遍历二叉树(网上查的)

voidPostOrderTraverse(BiTreeT,Status(*visit)(TElemTypee)){

if(T){

PostOrderTraverse(T->lchild,VISIT);

PostOrderTraverse(T->rchild,VISIT);

VISIT(T->data);

}

}

//采用非递归后序遍历二叉树(网上查的)

voidPostOrder(BiTNode*T,Status(*visit)(TElemTypee)){

BiTNode*p=T;

BiTNode*stack[30];

intnum=0;

BiTNode*have_visited=NULL;

while(NULL!

=p||num>0){

while(NULL!

=p){

stack[num++]=p;

p=p->lchild;

}

p=stack[num-1];

if(NULL==p->rchild||have_visited==p->rchild){

VISIT(p->data);

num--;

have_visited=p;

p=NULL;

}

else{

p=p->rchild;

}

}

}

//统计二叉树的叶子数

StatusCountLeaf(BiTreeT){

if(T){

if(!

(T->lchild)&&!

(T->rchild))

n++;

CountLeaf(T->lchild);

CountLeaf(T->rchild);

}

returnn;

}

//统计二叉树的深度

intdeep(BiTreeT){

intld,rd;

if(T){

ld=deep(T->lchild);

rd=deep(T->rchild);

return(ld+1)>(rd+1)?

(ld+1):

(rd+1);

}

else

returnERROR;

}

//--------基本操作的实现-----------

//linkstack.cpp

#include

#include

#include

#include"common.h"

typedefcharTElemType;

#include"BiTree.h"

typedefBiTreeSElemType;

#include"LinkStack.h"

//初始化一个带头结点的空栈

StatusInitStack(LinkStack**S){

*S=(LinkStack*)malloc(sizeof(LinkStack));

if(*S==NULL)

exit(OVERFLOW);

(*S)->next=NULL;

returnOK;

}

//入栈操作,将x的数据元素插入栈s中,使x成为新的栈顶元素

StatusPush(LinkStack*S,SElemTypex){

LinkStack*p,*q;

q=S;

p=(LinkStack*)malloc(sizeof(LinkStack));

if(!

p)

exit(OVERFLOW);

p->data=x;

p->next=NULL;

while(q->next)

q=q->next;

q->next=p;

returnOK;

}

//出栈操作,先将栈s的栈顶结点的值送到e所指向的内存单元,然后删除栈顶结点

StatusPop(LinkStack*S,SElemType&e){

LinkStack*p,*q;

p=S;

if(S->next==NULL)

returnERROR;

while(p->next){

q=p;

p=p->next;

}

q->next=NULL;

e=p->data;

free(p);

returnOK;

}

//判断栈是否为空

StatusStackEmpty(LinkStack*S){

if(S->next==NULL)

returnTRUE;

else

returnFALSE;

}

//取栈顶元素

StatusGetTop(LinkStack*S,SElemType&e){

LinkStack*p,*q;

p=S;

if(S->next==NULL)

returnERROR;

while(p->next){

q=p;

p=p->next;

}

e=p->data;

returnOK;

}

//--------主程序--------

//main.cpp

#include

#include

#include"common.h"

typedefcharTElemType;

#include"BiTree.h"

typedefBiTreeSElemType;

#include"LinkStack.h"

voidmain(){

BiTreeT;

intHeight,Num;//树的深度和叶子个数

printf("按先序次序输入二叉树中结点的值,空格表示空树。

请输入:

\n");

PreCreateBiTree(T);

printf("先序遍历得到的序列为:

");

PreOrderTraverse(T,VISIT);

printf("\n");

printf("中序遍历得到的序列为:

");

//MidVisit(T);//递归中序遍历

//printf("\n");

InOrderTraverse(T,VISIT);

printf("\n");

printf("后序遍历得到的序列为:

");

PostOrder(T,VISIT);

printf("\n");

//PostOrderTraverse(T,VISIT);//递归后序遍历

//printf("\n");

Num=CountLeaf(T);

Height=deep(T);

printf("此树的深度和叶子个数分别为:

%d%d\n",Height,Num);

}

2.线索二叉树

//-------函数结果状态代码----------

//common.h

#defineTRUE1

#defineFALSE0

#defineOK1

#defineERROR0

#defineINFEASIBLE-1

#defineOVERFLOW-2

typedefintStatus;

//-------二叉树的二叉线索存储表示---------

//BiThrTree.h

typedefenum{Link,Thread}PointerTag;//Link==0,表示指针;Thread==1,表示线索

typedefstructBiThrNode{

TElemTypedata;

structBiThrNode*lchild,*rchild;//左右孩子指针

PointerTagLTag,RTag;//左右标志

}BiThrNode,*BiThrTree;

//-------基本操作的函数原型说明--------

BiThrTreePreCreateBiTree();

voidInThreading(BiThrTreep);

BiThrTreeInOrderThreading(BiThrTree&t,BiThrTreeT);

BiThrTreeInOrderThrTree(BiThrTreeT);

voidInThrTravel(BiThrTreeThre);

//--------基本操作的实现-----------

//bithrtree.cpp

#include

#include

#include

#include"common.h"

typedefcharTElemType;

#include"BiThrTree.h"

BiThrTreepre;

//构造而二叉链表表示的二叉树

//插入元素,按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树

BiThrTreePreCreateBiTree()//递归先序建立{

BiThrTreeT;

chare;

scanf("%c",&e);

if(e=='')

T=NULL;

else{

T=(BiThrTree)malloc(sizeof(BiThrNode));

T->data=e;

T->LTag=Link;/*初始化时指针标志均为Link*/

T->RTag=Link;

T->lchild=PreCreateBiTree();

T->rchild=PreCreateBiTree();

}

returnT;

}

voidInThreading(BiThrTreep){

if(p){

InThreading(p->lchild);//左子树线索化

if(!

p->lchild)

{//前驱线索

p->LTag=Thread;

p->lchild=pre;

}

if(!

pre->rchild)

{//后继线索

pre->RTag=Thread;

pre->rchild=p;

}

pre=p;//保持pre指向p的前驱

InThreading(p->rchild);//右子树线索化

}

}

//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点

BiThrTreeInOrderThreading(BiThrTree&t,BiThrTreeT){

t=(BiThrTree)malloc(sizeof(BiThrNode));

if(!

t)

exit(OVERFLOW);

t->LTag=Link;t->RTag=Thread;//建头结点

t->rchild=t;//右指针回指

if(!

T)

t->lchild=t;

else{

t->lchild=T;

pre=t;

InThreading(T);//中序遍历进行中序线索化

pre->rchild=t;pre->RTag=Thread;//最后一个结点线索化

t->rchild=pre;

}

returnt;

}

//网上找的

BiThrTreeInOrderThrTree(BiThrTreeT)/*中序线索化二叉树*/{

BiThrTreeThre;/*Thre为头结点的指针*/

Thre=(BiThrTree)malloc(sizeof(BiThrNode));

Thre->lchild=T;

Thre->rchild=Thre;

pre=Thre;

InThreading(T);

pre->RTag=Thread;

pre->rchild=Thre;

Thre->rchild=pre;

returnThre;

}

//网上找的

/*中序遍历二叉树*/

voidInThrTravel(BiThrTreeThre){

BiThrTreep;

p=Thre->lchild;

while(p!

=Thre)/*指针回指向头结点时结束*/

{

while(p->LTag==Link)

p=p->lchild;

printf("%c",p->data);

while(p->RTag==Thread&&p->rchild!

=Thre){

p=p->rchild;

printf("%c",p->data);

}

p=p->rchild;

}

}

//--------主程序--------

//main.cpp

#include

#include

#include

#include"common.h"

typedefcharTElemType;

#include"BiThrTree.h"

voidmain(){

BiThrTreeT,Thre,t;

printf("先序初始化二叉树:

\n");

T=PreCreateBiTree();

Thre=InOrderThreading(t,T);

//Thre=InOrderThrTree(T);//网上找的

printf("中序遍历线索化后的二叉树:

\n");

InThrTravel(Thre);

printf("\n");

}

3.赫夫曼树和赫夫曼编码

//-------函数结果状态代码----------

//common.h

#defineTRUE1

#defineFALSE0

#defineOK1

#defineERROR0

#defineINFEASIBLE-1

#defineOVERFLOW-2

typedefintStatus;

//-------赫夫曼树和赫夫曼编码的存储表示---------

//HuffmanTree.h

typedefstruct{

unsignedintweight;//权

unsignedintparent,lchild,rchild;

}HTNode,*HuffmanTree;//动态分配数组存储赫夫曼树

typedefchar**HuffmanCode;//动态分配数组存储赫夫曼编码表

//-------基本操作的函数原型说明--------

intMIN(HuffmanTreet,inti);

voidSelect(HuffmanTreet,intn,int&s1,int&s2);

voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*w,intn);

//--------基本操作的实现-----------

//huffmantree.cpp

#include

#include

#include

#include

#include"common.h"

#include"HuffmanTree.h"

//返回i个结点中权值最小的树的根结点序号

intMIN(HuffmanTreet,inti){

intj,flag;

unsignedintk=65535;/*取k为无符号整型最大值*/

for(j=1;j<=i;j++){

if(t[j].weight

k=t[j].weight;

flag=j;

}

}

t[flag].parent=1;/*给选中的根结点的双亲赋1,避免第2次查找该结点*/

returnflag;

}

//在i个结点中选择2个权值最小的树的根结点序号,s1为其中序号小的那个

voidSelect(HuffmanTreet,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 表格类模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1