武汉纺织大学数据结构实验报告2.docx
《武汉纺织大学数据结构实验报告2.docx》由会员分享,可在线阅读,更多相关《武汉纺织大学数据结构实验报告2.docx(18页珍藏版)》请在冰豆网上搜索。
![武汉纺织大学数据结构实验报告2.docx](https://file1.bdocx.com/fileroot1/2022-12/31/75505281-9efe-4b06-85bc-5f69c3312745/75505281-9efe-4b06-85bc-5f69c33127451.gif)
武汉纺织大学数据结构实验报告2
武汉纺织大学《数据结构》实验报告
班级:
专业班姓名:
序号:
实验时间:
年月日指导教师:
实验二:
二叉树操作及应用
一、实验目的:
1、掌握二叉树的基本概念、基本操作以及各种存储结构。
2、掌握二叉树的多种遍历方法。
2、掌握哈夫曼树以及哈夫曼编码的求取过程。
二、实验内容:
1、编写一个程序,生成一棵二叉树并进行基本操作。
实验步骤:
①、在Java语言编辑环境中新建程序,输入程序内容,并保存和编译;
②、运行程序,从键盘输入二叉树各个结点数据,参考书本173页【例6.1】;
③、显示菜单如下:
1——先序遍历
2——中序遍历
3——后序遍历
4——层次遍历
5——求结点总数
6——求高度
0——退出
④、输入菜单选项,进行相应操作并输出结果。
⑤可参考程序为:
172页先序、中序、后序遍历;174页求结点个数、求高度;185页层次遍历。
2、编写一个程序,构造哈夫曼树并获取哈夫曼编码。
实验步骤:
①、在Java语言编辑环境中新建程序,参考书本205-207页程序内容,并保存和编译;
②、运行程序,根据指定权值,建立哈夫曼树;
③、输出哈夫曼树存储结构信息;
④、输出各个哈夫曼编码。
⑤、如有能力,请将此程序修改为:
从键盘上输入权值,并构造哈夫曼树、获取哈夫曼编码。
3、编写程序,实现对二叉树的中序线索化操作。
实验步骤:
①、在Java语言编辑环境中新建程序,参考书本190-193页程序内容,并保存和编译;
②、运行程序,建立二叉树存储结构;
③、对二叉树进行中序线索化,建立中序线索二叉树;
④、输出中序遍历序列。
三、操作步骤:
1.二叉树
(1)接口类BinaryTTree.java
packagetree;
publicinterfaceBinaryTTree{//二叉树接口,二叉树抽象数据类型
booleanisEmpty();//判断二叉树是否为空
intcount();//返回二叉树的结点个数
intheight();//返回二叉树的高度
voidpreOrder();//先根次序遍历二叉树
voidinOrder();//中根次序遍历二叉树
voidpostOrder();//后根次序遍历二叉树
voidlevelOrder();//按层次遍历二叉树
BinaryNodesearch(Tkey);//查找并返回首次出现的关键字为key元素结点
BinaryNodegetParent(BinaryNodenode);//返回node的父母结点
voidinsertRoot(Tx);//插入元素x作为根节点
BinaryNodeinsertChild(BinaryNodep,Tx,booleanleftChild);//插入孩子节点
voidremoveChild(BinaryNodep,booleanleftChild);//删除p结点的左或右子树
voidremoveAll();//删除二叉树
}
(2)二叉链表结点类BinaryNode.java
packagetree;
publicclassBinaryNode{//二叉树的二叉链表结点类
publicTdata;//数据域,存储数据元素
publicBinaryNodeleft,right;//链域,分别指向左、右孩子结点
//构造结点,参数分别指定元素和左、右孩子结点
publicBinaryNode(Tdata,BinaryNodeleft,BinaryNoderight){
this.data=data;
this.left=left;
this.right=right;
}
publicBinaryNode(Tdata){this(data,null,null);}//构造指定值的叶子节点
publicBinaryNode(){this(null,null,null);}
}
(3)二叉树类BinaryTree.java
packagetree;
//二叉树类,实现BinaryTree接口,泛型T指定节点的元素类型
publicclassBinaryTreeimplementsBinaryTTree{
publicBinaryNoderoot;
publicBinaryTree(){this.root=null;}
publicbooleanisEmpty(){
returnthis.root==null;
}
publicintcount(){returncount(root);}
publicintcount(BinaryNodep){
if(p==null)
return0;
return1+count(p.left)+count(p.right);
}
publicintheight(){returnheight(root);}
publicintheight(BinaryNodep){
if(p==null)
return0;
intlh=height(p.left);
intrh=height(p.right);
return(lh>rh)?
lh+1:
rh+1;
}
publicvoidpreOrder(){
System.out.print("先根次序遍历:
");
preOrder(root);
System.out.println();
}
publicvoidpreOrder(BinaryNodep){
if(p!
=null){
System.out.print(p.data.toString()+"");
preOrder(p.left);
preOrder(p.right);
}
}
publicvoidinOrder(){
System.out.print("中根次序遍历:
");
inOrder(root);
System.out.println();
}
publicvoidinOrder(BinaryNodep){
if(p!
=null){
inOrder(p.left);
System.out.print(p.data.toString()+"");
inOrder(p.right);
}
}
publicvoidpostOrder(){
System.out.print("后根次序遍历:
");
postOrder(root);
System.out.println();
}
publicvoidpostOrder(BinaryNodep){
if(p!
=null){
postOrder(p.left);
postOrder(p.right);
System.out.print(p.data.toString()+"");
}
}
publicvoidlevelOrder(){//按层次遍历二叉树
LinkedQueue>que=newLinkedQueue>();//创建空队列
BinaryNodep=this.root;
System.out.print("层次遍历:
");
while(p!
=null){
System.out.print(p.data+"");
if(p.left!
=null)
que.enqueue(p.left);//p的左孩子结点入队
if(p.right!
=null)
que.enqueue(p.right);//p的右孩子结点入队
p=que.dequeue();//p指向出队结点,若队列空返回null
}
System.out.println();
}
}
(4)使用二叉树UseBinaryTree.java
packagetree;
importjava.util.Scanner;
/**
*
*@authorpang
*
*/
publicclassUseBinaryTree{
publicstaticBinaryTreemake(Stringa,Stringb,Stringc,Stringd,Stringe,Stringf,Stringg,Stringh){
BinaryTreebitree=newBinaryTree();
BinaryNodechild_f,child_d,child_b,child_c;
child_d=newBinaryNode(d,null,newBinaryNode(g));
child_b=newBinaryNode(b,child_d,null);
child_f=newBinaryNode(f,newBinaryNode(h),null);
child_c=newBinaryNode(c,newBinaryNode(e),child_f);
bitree.root=newBinaryNode(a,child_b,child_c);
returnbitree;
}
publicstaticvoidmain(Stringargs[]){
System.out.println("请输入结点数据:
");
Scannerscan=newScanner(System.in);
Stringa=scan.next();
Stringb=scan.next();
Stringc=scan.next();
Stringd=scan.next();
Stringe=scan.next();
Stringf=scan.next();
Stringg=scan.next();
Stringh=scan.next();
BinaryTreebitree=make(a,b,c,d,e,f,g,h);
System.out.println("1--先序遍历\n2--中序遍历\n3--后序遍历\n4--层次遍历\n5--求结点总数\n6--求高度\n0--退出");
System.out.println("输入菜单选项,进行相应操作并输出结果");
while(true){
intnumber=scan.nextInt();
operate(bitree,number);
}
}
//菜单功能方法
publicstaticvoidoperate(BinaryTreebitree,inta){
switch(a){
case1:
bitree.preOrder();
break;
case2:
bitree.inOrder();
break;
case3:
bitree.postOrder();
break;
case4:
bitree.levelOrder();
break;
case5:
System.out.println("二叉树结点数:
"+bitree.count());
break;
case6:
System.out.println("二叉树高度:
"+bitree.height());
break;
case0:
System.exit(0);
default:
System.out.println("请正确输入指令!
");
}
}
}
(5)注意事项
二叉树类BinaryTree.java中有用到队列部分内容,需要导入包或者将该部分文件放入tree包中才能使用
(6)运行结果:
2.哈夫曼树
(1)二叉树的静态三叉链表结点类TriElement.java
packagehuffman;
publicclassTriElement{//二叉树的三叉静态链表结点类
intdata;//数据域,表示权值
intparent,left,right;//父母结点和左、右孩子结点下标
publicTriElement(intdata,intparent,intleft,intright){
this.data=data;
this.parent=parent;
this.left=left;
this.right=right;
}
publicTriElement(intdata){this(data,-1,-1,-1);}
publicTriElement(){this(0);}
publicStringtoString(){return"("+this.data+","+this.parent+","+this.left+","+this.right+")";}
}
(2)哈夫曼树类HuffmanTree.java
packagehuffman;
publicclassHuffmanTree{//Huffman树
privateintleafNum;//叶子结点
privateTriElement[]huftree;//Huffman树的结点数组
publicHuffmanTree(int[]weight){//构造指定权值集合的Huffman树
intn=weight.length;//n个叶子结点
this.leafNum=n;
this.huftree=newTriElement[2*n-1];//n个叶子结点的Huffman树共有2n-1个结点
for(inti=0;ithis.huftree[i]=newTriElement(weight[i]);
for(inti=0;iintmin1=Integer.MAX_VALUE,min2=min1;//最小和次最小权值,初值为整数最大值
intx1=-1,x2=-1;//记录两个无父母的最小权值结点下标
for(intj=0;jif(huftree[j].datamin2=min1;
x2=x1;
min1=huftree[j].data;//min1记下最小权值
x1=j;//x1记下最小权值结点的下标
}
elseif(huftree[j].datamin2=huftree[j].data;
x2=j;//x2记下次最小权值结点的下标
}
huftree[x1].parent=n+i;//将找出的两棵权值最小的子树合并为一棵子树
huftree[x2].parent=n+i;
this.huftree[n+i]=newTriElement(huftree[x1].data+huftree[x2].data,-1,x1,x2);
}
}
publicStringtoString(){
Stringstr="Huffman树的结点数组:
\n";
for(inti=0;i=null;i++)
str+="第"+i+"行"+this.huftree[i].toString()+"\n";
returnstr;
}
publicString[]huffmanCodes(){//返回当前Huffman树的Huffman编码
String[]hufcodes=newString[this.leafNum];
for(inti=0;ihufcodes[i]="";
intchild=i;
intparent=huftree[child].parent;
while(parent!
=-1){//由叶子结点向上直到根节点循环
if(huftree[parent].left==child)
hufcodes[i]="0"+hufcodes[i];//左孩子结点编码为0
else
hufcodes[i]="1"+hufcodes[i];//右孩子结点编码为1
child=parent;
parent=huftree[child].parent;
}
}
returnhufcodes;
}
}
(3)获取哈夫曼编码HuffmanTree_example.java
packagehuffman;
importjava.util.Scanner;
importJosephus.SeqList;
/**
*
*@authorpang
*
*/
publicclassHuffmanTree_example{
publicstaticvoidmain(Stringargs[]){
SeqListlist=newSeqList();
System.out.println("请依次输入权值并以0结束作为标识");
Scannerscan=newScanner(System.in);
while(true){
intx=scan.nextInt();
if(x!
=0)
list.append(x);
else
break;
}
int[]weight=newint[list.length()];
for(inti=0;iweight[i]=list.get(i);
}
HuffmanTreehtree=newHuffmanTree(weight);
System.out.print(htree.toString());
String[]code=htree.huffmanCodes();
System.out.print("Huffman编码:
\n");
for(inti=0;iSystem.out.println((char)('A'+i)+":
"+code[i]+"");
}
}
(4)注意事项
从键盘输入权值且不确定个数,需要一个标识符,这里用了0作为标识符。
使用到了线性表部分内容,需要导入包或将文件放入此包中。
(5)运行结果:
3.二叉树的中序线索化
(1)二叉链表结点类ThreadNode.java
packagethreadBinaryTree;
publicclassThreadNode{
publicTdata;
publicThreadNodeleft,right;
publicintltag,rtag;
publicThreadNode(Tdata,ThreadNodeleft,intltag,ThreadNoderight,intrtag){
this.data=data;
this.left=left;
this.ltag=ltag;
this.right=right;
this.rtag=rtag;
}
publicThreadNode(Tdata){this(data,null,0,null,0);}
publicThreadNode(){this(null,null,0,null,0);}
}
(2)中序线索二叉树类ThreadBinaryTree.java
packagethreadBinaryTree;
publicclassThreadBinaryTree{
publicThreadNoderoot;
publicThreadBinaryTree(){
this.root=null;
}
publicbooleanisEmpty(){
returnroot==null;
}
publicThreadBinaryTree(T[]prelist){
this.root=create(prelist);
inorderThread(this.root);
}
privateinti=0;
privateThreadNodecreate(T[]prelist){
ThreadNodep=null;
if(iTelem=prelist[i++];
if(elem!
=null){
p=newThreadNode(elem);
p.left=create(prelist);
p.right=