实验四 二叉树基本操作
二叉树的基本操作
二叉树的基本操作二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。
二叉树在计算机领域中得到广泛应用,它的基本操作包括插入、删除、查找、遍历等。
1.插入操作:二叉树的插入操作是将一个新的节点添加到已有的二叉树中的过程。
插入操作会按照一定规则将新节点放置在正确的位置上。
插入操作的具体步骤如下:-首先,从根节点开始,比较新节点的值与当前节点的值的大小关系。
-如果新节点的值小于当前节点的值,则将新节点插入到当前节点的左子树中。
-如果新节点的值大于当前节点的值,则将新节点插入到当前节点的右子树中。
-如果当前节点的左子树或右子树为空,则直接将新节点插入到该位置上。
-如果当前节点的左子树和右子树都不为空,则递归地对左子树或右子树进行插入操作。
2.删除操作:二叉树的删除操作是将指定节点从二叉树中删除的过程。
删除操作有以下几种情况需要考虑:-如果待删除节点是叶子节点,则直接将其从二叉树中删除即可。
-如果待删除节点只有一个子节点,则将其子节点替换为待删除节点的位置即可。
-如果待删除节点有两个子节点,则需要找到其左子树或右子树中的最大节点或最小节点,将其值替换为待删除节点的值,然后再删除最大节点或最小节点。
3.查找操作:二叉树的查找操作是在二叉树中查找指定值的节点的过程。
查找操作的具体步骤如下:-从根节点开始,将待查找值与当前节点的值进行比较。
-如果待查找值等于当前节点的值,则返回该节点。
-如果待查找值小于当前节点的值,则在当前节点的左子树中继续查找。
-如果待查找值大于当前节点的值,则在当前节点的右子树中继续查找。
-如果左子树或右子树为空,则说明在二叉树中找不到该值。
4.遍历操作:二叉树的遍历操作是按照一定规则依次访问二叉树中的每个节点。
有三种常用的遍历方式:- 前序遍历(Preorder Traversal):先访问根节点,然后递归地前序遍历左子树和右子树。
- 中序遍历(Inorder Traversal):先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。
实验四 二叉树操作实现
实验四二叉树操作实现
一、目的:
掌握二叉树的定义、性质及存储方式,各种遍历算法。
二、要求:
采用二叉树链表作为存储结构,完成二叉树的建立,先序、中序和后序以及按层次遍历的操作,求所有叶子及结点总数的操作。
三、实验内容
1、二叉树的基本操作。
2、调试程序,设计一棵二叉树,输入完全二叉树的先序序列,用#代表虚结点(空指针),
如ABD###CE##F##,建立二叉树,求出先序、中序和后序以及按层次遍历序列,求所有叶子及结点总数。
四、实验报告要求
要求所编的程序能正确运行,并提交实验报告。
实验报告的基本要求为:
1、陈述程序设计的任务,强调程序要做什么,明确规定:
(1)输入的形式和输出值的范围;
(2)输出的形式;
(3)程序所能达到的功能;
(4)测试数据:包括正确的输入输出结果和错误的输入及输出结果。
2、说明用到的数据结构定义、主程序的流程及各程序模块之间的调用关系。
3、提交带注释的源程序或者用伪代码写出每个操作所涉及的算法。
4、调试分析:
(1)调试过程中所遇到的问题及解决方法;
(2)算法的时空分析;
(3)经验与体会。
5、用户使用说明:说明如何使用你的程序,详细列出每一步操作步骤。
6、测试结果:列出对于给定的输入所产生的输出结果。
(完整版)C++二叉树基本操作实验报告
一、实验目的选择二叉链式存储结构作为二叉树的存储结构,设计一个程序实现二叉树的基本操作(包括建立、输出、前序遍历、中序遍历、后序遍历、求树高、统计叶子总数等)二、实验开发环境Windows 8.1 中文版Microsoft Visual Studio 6.0三、实验内容程序的菜单功能项如下:1------建立一棵二叉树2------前序遍历递归算法3------前序遍历非递归算法4------中序遍历递归算法5------中序遍历非递归算法6------后序遍历递归算法7------后序遍历非递归算法8------求树高9------求叶子总数10-----输出二叉树11-----退出四、实验分析1、建立一棵二叉树2、输入二叉树各节点数据cout<<"请按正确顺序输入二叉树的数据:";cin.getline(t,1000); //先把输入的数据输入到一个t数组3、递归前序遍历void BL1(ECS_data *t){if(NULL!=t){cout<<t->data<<",";BL1(t->l);BL1(t->r);}}4、非递归前序遍历void preOrder2(ECS_data *t){stack<ECS_data*> s;ECS_data *p=t;while(p!=NULL||!s.empty()){while(p!=NULL){cout<<p->data<<" ";s.push(p);p=p->l;}if(!s.empty()){p=s.top();s.pop();p=p->r;}}}5、递归中序遍历void BL2(ECS_data *t){if(NULL!=t){BL2(t->l);cout<<t->data<<",";BL2(t->r);}}6、非递归中序遍历void inOrder2(ECS_data *t) //非递归中序遍历{stack<ECS_data*> s;ECS_data *p=t;while(p!=NULL||!s.empty()){while(p!=NULL){s.push(p);p=p->l;}if(!s.empty()){p=s.top();cout<<p->data<<" ";s.pop();p=p->r;}}}7、递归后序遍历void BL3(ECS_data *t){if(NULL!=t){BL3(t->l);BL3(t->r);cout<<t->data<<",";}}8、非递归后序遍历void postOrder3(ECS_data *t){stack<ECS_data*> s;ECS_data *cur; //当前结点ECS_data *pre=NULL; //前一次访问的结点s.push(t);while(!s.empty()){cur=s.top();if((cur->l==NULL&&cur->r==NULL)||(pre!=NULL&&(pre==cur->l||pre==cur->r))){cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过s.pop();pre=cur;}else{if(cur->r!=NULL)s.push(cur->r);if(cur->l!=NULL)s.push(cur->l);}}}9、求树高int Height (ECS_data *t){if(t==NULL) return 0;else{int m = Height ( t->l );int n = Height(t->r);return (m > n) ? (m+1) : (n+1);}}10、求叶子总数int CountLeaf(ECS_data *t){static int LeafNum=0;//叶子初始数目为0,使用静态变量if(t)//树非空{if(t->l==NULL&&t->r==NULL)//为叶子结点LeafNum++;//叶子数目加1else//不为叶子结点{CountLeaf(t->l);//递归统计左子树叶子数目CountLeaf(t->r);//递归统计右子树叶子数目}}return LeafNum;}五、运行结果附:完整程序源代码://二叉树链式存储的实现#include<iostream>#include<cstring>#include <stack>using namespace std;struct ECS_data //先定义好一个数据的结构{char data;ECS_data *l;ECS_data *r;};class ECS{private://int level; //树高int n; //表示有多少个节点数int n1; //表示的是数组的总长度值,(包括#),因为后面要进行删除判断ECS_data *temp[1000];public:ECS_data *root;ECS() //初始化{ECS_data *p;char t[1000];int i;int front=0,rear=1; //front表示有多少个节点,rear表示当前插入的点的父母cout<<"请按正确顺序输入二叉树的数据:";cin.getline(t,1000); //先把输入的数据输入到一个t数组//cout<<t<<" "<<endl;int n1=strlen(t); //测量数据的长度n=0;for(i=0;i<n1;i++){if(t[i]!='#'){p=NULL;if(t[i]!=',') //满足条件并开辟内存{n++;p=new ECS_data;p->data=t[i];p->l=NULL;p->r=NULL;}front++;temp[front]=p;if(1 == front){root=p;}else{if((p!=NULL)&&(0==front%2)){temp[rear]->l=p;//刚开始把这里写成了==}if((p!=NULL)&&(1==front%2)){temp[rear]->r=p;}if(1==front%2)rear++; //就当前的数据找这个数据的父母}}}}~ECS() //释放内存{int i;for(i=1;i<=n;i++)if(temp[i]!=NULL)delete temp[i];}void JS() //记录节点的个数{int s;s=n;cout<<"该二叉树的节点数为:"<<s<<endl;}void BL1(ECS_data *t)//递归前序遍历{if(NULL!=t){cout<<t->data<<",";BL1(t->l);BL1(t->r);}}void preOrder2(ECS_data *t) //非递归前序遍历{stack<ECS_data*> s;ECS_data *p=t;while(p!=NULL||!s.empty()){while(p!=NULL){cout<<p->data<<" ";s.push(p);p=p->l;}if(!s.empty()){p=s.top();s.pop();p=p->r;}}}void BL2(ECS_data *t)//递归中序遍历{if(NULL!=t){BL2(t->l);cout<<t->data<<",";BL2(t->r);}}void inOrder2(ECS_data *t) //非递归中序遍历{stack<ECS_data*> s;ECS_data *p=t;while(p!=NULL||!s.empty()){while(p!=NULL){s.push(p);p=p->l;}if(!s.empty()){p=s.top();cout<<p->data<<" ";s.pop();p=p->r;}}}void BL3(ECS_data *t)//递归后序遍历{if(NULL!=t){BL3(t->l);BL3(t->r);cout<<t->data<<",";}}void postOrder3(ECS_data *t) //非递归后序遍历{stack<ECS_data*> s;ECS_data *cur; //当前结点ECS_data *pre=NULL; //前一次访问的结点s.push(t);while(!s.empty()){cur=s.top();if((cur->l==NULL&&cur->r==NULL)||(pre!=NULL&&(pre==cur->l||pre==cur->r))){cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过s.pop();pre=cur;}else{if(cur->r!=NULL)s.push(cur->r);if(cur->l!=NULL)s.push(cur->l);}}}int Height (ECS_data *t) //求树高{if(t==NULL) return 0;else{int m = Height ( t->l );int n = Height(t->r);return (m > n) ? (m+1) : (n+1);}}int CountLeaf(ECS_data *t) //求叶子总数{static int LeafNum=0;//叶子初始数目为0,使用静态变量if(t)//树非空{if(t->l==NULL&&t->r==NULL)//为叶子结点LeafNum++;//叶子数目加1else//不为叶子结点{CountLeaf(t->l);//递归统计左子树叶子数目CountLeaf(t->r);//递归统计右子树叶子数目}}return LeafNum;}};int main(){ECS a;a.JS();cout<<"递归前序遍历:";a.BL1(a.root);cout<<endl;cout<<"非递归前序遍历:";a.preOrder2(a.root);cout<<endl;cout<<"递归中序遍历:";a.BL2(a.root);cout<<endl;cout<<"非递归中序遍历:";a.inOrder2(a.root);cout<<endl;cout<<"递归后序遍历:";a.BL3(a.root);cout<<endl;cout<<"非递归后序遍历:";a.postOrder3(a.root);cout<<endl;cout<<"树高为:"<<a.Height(a.root)<<endl;cout<<"叶子总数为:"<<a.CountLeaf(a.root)<<endl;return 0;}。
二叉树的顺序存储及基本操作
二叉树的顺序存储及基本操作二叉树的顺序存储是将树中的节点按照完全二叉树从上到下、从左到右的顺序依次存储到一个一维数组中,采用这种方式存储的二叉树也被称为完全二叉树。
一、在使用顺序存储方式时,可以使用以下公式来计算一个节点的左右子节点和父节点:
1. 左子节点:2i+1(i为父节点的在数组中的下标)
2. 右子节点:2i+2
3. 父节点:(i-1)/2(i为子节点在数组中的下标)
二、基本操作:
1. 创建二叉树:按照上述公式将节点存储到数组中。
2. 遍历二叉树:可采用递归或非递归方式,进行前序、中序、后序、层次遍历。
3. 插入节点:先将节点插入到数组末尾,然后通过比较节点和其父节点的大小,进行上浮操作直到满足二叉树的性质。
4. 删除节点:先将待删除节点和最后一个节点交换位置,然后通过比较交换后的节点和其父节点的大小,进行下沉操作直到满足二
叉树的性质。
5. 查找节点:根据节点值进行查找,可采用递归或非递归方式。
6. 修改节点:根据节点值进行查找,然后进行修改操作。
二叉树的基本操作实验报告
二叉树的基本操作实验报告学号姓名实验日期 2012-12-26实验室计算机软件技术实验指导教师设备编号 401实验内容二叉树的基本操作一实验题目实现二叉树的基本操作的代码实现二实验目的1、掌握二叉树的基本特性2、掌握二叉树的先序、中序、后序的递归遍历算法3、通过求二叉树的深度、度为2的结点数和叶子结点数等算法三实习要求(1)认真阅读书上给出的算法(2)编写程序并独立调试四、给出二叉树的抽象数据类型ADT BinaryTree{//数据对象D:D是具有相同特性的数据元素的集合。
//数据关系R:// 若D=Φ,则R=Φ,称BinaryTree为空二叉树;// 若D?Φ,则R={H},H是如下二元关系;// (1)在D中存在惟一的称为根的数据元素root,它在关系H下无前驱; // (2)若D-{root}?Φ,则存在D-{root}={D1,Dr},且D1?Dr =Φ; // (3)若D1?Φ,则D1中存在惟一的元素x1,<root,x1>?H,且存在D1上的关系H1 ?H;若Dr?Φ,则Dr中存在惟一的元素xr,<root,xr>?H,且存在上的关系Hr ?H;H={<root,x1>,<root,xr>,H1,Hr};// (4)(D1,{H1})是一棵符合本定义的二叉树,称为根的左子树;(Dr,{Hr})是一棵符合本定义的二叉树,称为根的右子树。
//基本操作:CreateBiTree( &T, definition ) // 初始条件:definition给出二叉树T的定义。
// 操作结果:按definiton构造二叉树T。
BiTreeDepth( T )// 初始条件:二叉树T存在。
// 操作结果:返回T的深度。
PreOrderTraverse( T, visit() ) // 初始条件:二叉树T存在,Visit是对结点操作的应用函数。
数据结构与算法实验——二叉树基本操作
二叉树基本操作实验报告实验名称二叉树基本操作实验目的1.熟悉二叉树结点的结构和二叉树的基本操作;2.掌握二叉树每种操作的具体实现;3.学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法;4.在二叉树基本操作的基础上掌握对二叉树的一些其它操作的具体实现方法;5.掌握构造哈夫曼树以及哈夫曼编码的方法。
实验内容编制一个演示二叉树创建、遍历、计算等操作的程序。
问题描述用数据结构相关知识,实现二叉树的定义和操作。
该程序包括二叉树结构类型以及对二叉树操作的具体的函数定义(包括:初始化二叉树、清空二叉树、检查二叉树是否为空、遍历二叉树(先序、后序、中序、层次)、求二叉树的深度、求二叉树所有节点数)。
问题分析该实验是基于C语言和数据结构知识基础的对二叉树的基本操作的检验,无需设计复杂的算法,程序语句也相对简单。
因此,我直接按要求定义了对二叉树操作的具体函数,并于主函数中实现对应的功能调用,其中,功能选择靠switch语句实现。
实验步骤1.需求分析本演示程序用VC++编写,完成二叉树的生成、遍历、计算等基本操作。
①输入的形式和输入值的范围:以字符(其中‘#’表示虚节点)的形式输入,以创建二叉树;在输入二叉树节点前,必须先确定该序列能正确创建二叉树。
②输出的形式:在所有三种操作中都显示操作是否正确以及操作后二叉树的内容。
③程序所能达到的功能:完成二叉树的生成、遍历(包括先序、后序、中序、层次四种方式)、计算等基本操作。
④测试数据:创建操作中依次输入a,b,d,#,g,#,#,#,c,e,#,#,f,#,#生成一个二叉树。
2.概要设计1)为了实现上述程序功能,需要定义二叉树的抽象数据类型:ADT BitTree {数据对象:由一个根节点和两个互不相交的左右子树构成数据关系:结点具有相同的数据类型及层次结构基本操作:Void BinTreeInit(BitTree *T)初始条件:无操作结果:初始化一棵二叉树Void BinTreeCreat(BitTree *T)初始条件:二叉树T已存在操作结果:按先序次序创建一棵二叉树2)本程序包含7个函数:①主函数main() ②初始化二叉树函数BinTreeInit() ③建立一棵二叉树函数BinTreeCreat() ④先序遍历函数PreOrderTraverse() ⑤中序遍历函数InOrderTraverse()⑥后序遍历函数PostOrderTraverse()⑦层次遍历函数LevelOrderTraverse()⑧求二叉树深度函数Countlevel()⑨检验空树函数BinTreeEmpty()⑩求节点数函数 Countnode()函数说明#include<stdio.h>#include<stdlib.h>typedef char Datatype;typedef struct NodeType{Datatype data;struct NodeType *lchild;struct NodeType *rchild;}BiTNode;typedef BiTNode * BinTree;//初始化二叉树。
数据结构二叉树实验报告
数据结构二叉树实验报告二叉树是一种常用的数据结构,它在计算机科学中有着广泛的应用。
本文将介绍二叉树的定义、基本操作以及一些常见的应用场景。
一、二叉树的定义和基本操作二叉树是一种特殊的树形结构,它的每个节点最多有两个子节点。
一个节点的左子节点称为左子树,右子节点称为右子树。
二叉树的示意图如下:```A/ \B C/ \D E```在二叉树中,每个节点可以有零个、一个或两个子节点。
如果一个节点没有子节点,我们称之为叶子节点。
在上面的示例中,节点 D 和 E 是叶子节点。
二叉树的基本操作包括插入节点、删除节点、查找节点和遍历节点。
插入节点操作可以将一个新节点插入到二叉树中的合适位置。
删除节点操作可以将一个指定的节点从二叉树中删除。
查找节点操作可以在二叉树中查找指定的节点。
遍历节点操作可以按照一定的顺序遍历二叉树中的所有节点。
二、二叉树的应用场景二叉树在计算机科学中有着广泛的应用。
下面将介绍一些常见的应用场景。
1. 二叉搜索树二叉搜索树是一种特殊的二叉树,它的每个节点的值都大于其左子树中的节点的值,小于其右子树中的节点的值。
二叉搜索树可以用来实现快速的查找、插入和删除操作。
它在数据库索引、字典等场景中有着重要的应用。
2. 堆堆是一种特殊的二叉树,它的每个节点的值都大于或小于其子节点的值。
堆可以用来实现优先队列,它在任务调度、操作系统中的内存管理等场景中有着重要的应用。
3. 表达式树表达式树是一种用来表示数学表达式的二叉树。
在表达式树中,每个节点可以是操作符或操作数。
表达式树可以用来实现数学表达式的计算,它在编译器、计算器等场景中有着重要的应用。
4. 平衡二叉树平衡二叉树是一种特殊的二叉树,它的左子树和右子树的高度差不超过1。
平衡二叉树可以用来实现高效的查找、插入和删除操作。
它在数据库索引、自平衡搜索树等场景中有着重要的应用。
三、总结二叉树是一种常用的数据结构,它在计算机科学中有着广泛的应用。
本文介绍了二叉树的定义、基本操作以及一些常见的应用场景。
二叉树的基本操作与实现实验报告
二叉树的基本操作与实现实验报告二叉树是一种重要的数据结构,在计算机科学领域中被广泛应用。
本实验将介绍二叉树的基本操作与实现,并给出相应的实验报告。
一、引言二叉树是一种特殊的树状结构,每个节点至多有两个子节点。
二叉树有许多重要的特性,如平衡二叉树、二叉树等,应用广泛。
在本实验中,我们将介绍二叉树的基本操作和实现。
二、实验目的1.掌握二叉树的基本概念和特性;2.熟悉二叉树的基本操作,包括创建、插入、删除、遍历等;3.学会使用编程语言实现二叉树的基本操作。
三、实验内容本实验主要包括以下内容:1.二叉树的定义和基本概念;2.二叉树的基本操作,包括创建、插入、删除、遍历等;3.使用编程语言实现二叉树的基本操作;4.测试和验证二叉树的基本操作的正确性。
四、实验步骤1.二叉树的定义和基本概念二叉树是一种树状结构,每个节点至多有两个子节点。
二叉树的每个节点包含一个数据项和指向左子树和右子树的指针。
二叉树的特性有很多,如完全二叉树、平衡二叉树、二叉树等。
2.二叉树的基本操作(1)创建二叉树:可以通过手动输入节点数据来创建二叉树,也可以通过读取文件中的数据来创建二叉树。
(2)插入节点:在指定位置插入一个新节点。
(3)删除节点:删除指定位置的节点。
(4)遍历二叉树:有前序遍历、中序遍历和后序遍历三种遍历方式。
3.使用编程语言实现二叉树的基本操作实现二叉树的基本操作可以使用编程语言来完成。
我们可以定义一个二叉树的结构体,包含节点数据和指向左右子树的指针。
然后根据具体的需求,实现相应的操作函数。
4.测试和验证二叉树的基本操作的正确性在完成二叉树的基本操作后,我们可以编写测试代码来验证操作的正确性。
通过创建二叉树,并进行插入、删除和遍历操作,观察输出结果是否符合预期。
五、实验结果与分析在完成二叉树的基本操作后,我们可以进行测试和验证。
通过输出二叉树的遍历结果,比对预期结果来判断操作是否正确。
同时,我们还可以观察二叉树的结构和特性,如是否满足平衡二叉树或二叉树的条件。
数据结构实验报告(二叉树的基本操作)
else LeafNum=LeafCount(root->LChild)+LeafCount(root->RChild);
//叶子数为左右子树数目之和
return LeafNum;
printf("\n菜单选择\n\n");
printf(" 1.树状输出二叉树2.先序遍历二叉树\n");
printf(" 3.中序遍历二叉树4.后序遍历二叉树\n");
printf(" 5.输出叶子结点6.输出叶子结点的个数\n");
printf(" 7.输出二叉树的深度8.退出\n");
printf("\n----------------------------------------------------------------------\n");
{
printf("\n\n");
j=j+1; k=0;
while(k<nlocate)
{
printf(" ");
k++;
}
}
while(k<(nlocate-1))
{
printf(" ");
k++;
}
printf("%c",bt->data );
q.front=q.front+1;
if(bt->LChild !=NULL)//存在左子树,将左子树根节点入队列
二叉树的基本操作
二叉树的基本操作二叉树是一种常见的数据结构,它由节点组成,每个节点最多连接两个子节点,分别称为左子节点和右子节点。
二叉树的基本操作包括创建、插入、删除、查找和遍历,下面将对这些操作进行详细介绍。
一、创建二叉树创建二叉树的方法有多种,其中最常用的是使用递归的方式。
递归创建二叉树时,可以先创建根节点,然后递归创建左子树和右子树。
如果子树为空,则使用特殊字符表示。
二、插入节点插入节点是向二叉树中添加新节点的操作。
插入节点的位置通常由二叉树的特性决定,左子节点小于父节点,右子节点大于父节点。
插入节点时,需要先找到插入位置,然后创建新节点,并将其连接到对应的位置。
三、删除节点删除节点是从二叉树中移除指定节点的操作。
删除节点的方式取决于节点的位置和子节点的情况。
如果要删除的节点是叶子节点,则直接将其删除即可。
如果要删除的节点有一个子节点,则将其子节点连接到父节点。
如果要删除的节点有两个子节点,则需要找到替代节点,将替代节点的值复制到当前位置,并将替代节点删除。
四、查找节点查找节点是在二叉树中寻找特定节点的操作。
常用的方式有深度优先(DFS)和广度优先(BFS)。
深度优先通常使用递归实现,分为前序遍历、中序遍历和后序遍历三种方式。
广度优先通常使用队列实现,先访问根节点,然后访问其所有子节点,再逐层访问下去,直到找到目标节点或遍历完整棵树。
五、遍历二叉树遍历二叉树是指按照一定顺序访问二叉树中的所有节点,常用的方式有前序遍历、中序遍历和后序遍历。
前序遍历先访问根节点,然后递归遍历左子树和右子树;中序遍历先递归遍历左子树,然后访问根节点,再遍历右子树;后序遍历先递归遍历左子树和右子树,然后访问根节点。
以上是二叉树的基本操作,通过这些操作可以有效地管理和处理二叉树数据结构。
在实际应用中,二叉树常用于、排序和表达等方面,因为它具有较高的查询效率和灵活性。
对于使用二叉树的相关算法和数据结构,理解和掌握其基本操作是非常重要的。
二叉树基本操作--实验报告
宁波工程学院电信学院计算机教研室实验报告一、实验目的1、熟悉二叉树树的基本操作。
2、掌握二叉树的实现以及实际应用。
3、加深二叉树的理解,逐步培养解决实际问题的编程能力。
二、实验环境1台WINDOWS环境的PC机,装有Visual C++ 6.0。
三、实验内容【问题描述】现需要编写一套二叉树的操作函数,以便用户能够方便的利用这些函数来实现自己的应用。
其中操作函数包括:1>创建二叉树CreateBTNode(*b,*str):根据二叉树括号表示法的字符串*str生成对应的链式存储结构。
2>输出二叉树DispBTNode(*b):以括号表示法输出一棵二叉树。
3>查找结点FindNode(*b,x):在二叉树b中寻找data域值为x的结点,并返回指向该结点的指针。
4>求高度BTNodeDepth(*b):求二叉树b的高度。
若二叉树为空,则其高度为0;否则,其高度等于左子树与右子树中的最大高度加l。
5>求二叉树的结点个数NodesCount(BTNode *b)6>先序遍历的递归算法:void PreOrder(BTNode *b)7>中序遍历的递归算法:void InOrder(BTNode *b)8>后序遍历递归算法:void PostOrder(BTNode *b)9>层次遍历算法void LevelOrder(BTNode *b)【基本要求】实现以上9个函数。
主函数中实现以下功能:创建下图中的树b输出二叉树b找到’H’节点,输出其左右孩子值输出b的高度输出b的节点个数输出b的四种遍历顺序上图转化为二叉树括号表示法为A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))程序:#include <stdio.h>#include <malloc.h>#define MaxSize 100typedef char ElemType;typedef struct node{ElemType data; /*数据元素*/struct node *lchild; /*指向左孩子*/struct node *rchild; /*指向右孩子*/} BTNode;void CreateBTNode(BTNode *&b,char *str);//创建BTNode *FindNode(BTNode *b,ElemType x);//查找节点int BTNodeHeight(BTNode *b);//求高度void DispBTNode(BTNode *b);//输出int NodesCount(BTNode *b);//二叉树的结点个数void PreOrder(BTNode *b);//先序遍历递归void InOrder(BTNode *b);//中序遍历递归void PostOrder(BTNode *b);//后序遍历递归void LevelOrder(BTNode *b);//层次遍历//创建void CreateBTNode(BTNode *&b,char *str){BTNode *St[MaxSize],*p=NULL;int top=-1,k,j=0;char ch;b=NULL;ch=str[j];while(ch!='\0'){switch(ch){case '(':top++;St[top]=p;k=1;break;case ')':top--;break;case ',':k=2;break;default:p=(BTNode *)malloc(sizeof(BTNode));p->data=ch;p->lchild=p->rchild=NULL;if(b==NULL)b=p;else{switch(k){case 1:St[top]->lchild=p;break;case 2:St[top]->rchild=p;break;}}}j++;ch=str[j];}}//输出void DispBTNode(BTNode *b){if(b!=NULL){printf("%c",b->data);if(b->lchild!=NULL||b->rchild!=NULL){printf("(");DispBTNode(b->lchild);if(b->rchild!=NULL)printf(",");DispBTNode(b->rchild);printf(")");}}}//查找节点BTNode *FindNode(BTNode *b,ElemType x){BTNode *p;if(b==NULL)return b;else if(b->data==x)return b;else{p=FindNode(b->lchild,x);if(p!=NULL)return p;elsereturn FindNode(b->rchild,x);}}//求高度int BTNodeHeight(BTNode *b){int lchildh,rchildh;if(b==NULL)return (0);else{lchildh=BTNodeHeight(b->lchild);rchildh=BTNodeHeight(b->rchild);return(lchildh>rchildh)?(lchildh+1):(rchildh+1);}}//二叉树的结点个数int NodesCount(BTNode *b){if(b==NULL)return 0;elsereturn NodesCount(b->lchild)+NodesCount(b->rchild)+1;}//先序遍历递归void PreOrder(BTNode *b){if(b!=NULL){printf("%c",b->data);PreOrder(b->lchild);PreOrder(b->rchild);}}//中序遍历递归void InOrder(BTNode *b){if(b!=NULL){InOrder(b->lchild);printf("%c",b->data);InOrder(b->rchild);}}//后序遍历递归void PostOrder(BTNode *b){if(b!=NULL){PostOrder(b->lchild);PostOrder(b->rchild);printf("%c",b->data);}}//层次遍历void LevelOrder(BTNode *b){BTNode *p;BTNode *qu[MaxSize];int front,rear;front=rear=-1;rear++;qu[rear]=b;while(front!=rear){front=(front+1)%MaxSize;p=qu[front];printf("%c",p->data);if(p->lchild!=NULL){rear=(rear+1)%MaxSize;qu[rear]=p->lchild;}if(p->rchild!=NULL){rear=(rear+1)%MaxSize;qu[rear]=p->rchild;}}}void main(){BTNode *b,*p,*lp,*rp;char str[]="A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))";//根据树形图改写成的//二叉树括号表示法的字符串*str//char str[100];scanf("%s",&str);//自行输入括号表示的二叉树CreateBTNode(b,str); //创建树bprintf("\n");printf("输出二叉树:");//输出二叉树bDispBTNode(b);printf("\n");printf("'H'结点:");//找到'H'节点,输出其左右孩子值p=FindNode(b,'H');printf("\n");if (p!=NULL){printf("左孩子节点的值");printf("%c",p->lchild->data);printf("\n");printf("右孩子节点的值");printf("%c",p->rchild->data);printf("\n");//此处输出p的左右孩子节点的值}printf("\n");printf("二叉树b的深度:%d\n",BTNodeHeight(b));//输出b的高度printf("二叉树b的结点个数:%d\n",NodesCount(b));//输出b的节点个数printf("\n");printf(" 先序遍历序列:\n");//输出b的四种遍历顺序printf(" 算法:");PreOrder(b);printf("\n");printf(" 中序遍历序列:\n");printf(" 算法:");InOrder(b);printf("\n");printf(" 后序遍历序列:\n");printf(" 算法:");PostOrder(b);printf("\n");printf(" 层次遍历序列:\n");printf(" 算法:");LevelOrder(b); printf("\n");}四、实验心得与小结通过实验,我熟悉二叉树树的基本操作,掌握二叉树的实现以及实际应用。
实验 4:二叉树的操作
实验4:二叉树的操作
【问题描述】
二叉树是一种常用的非线性数据结构。
设计一个程序,实现对二叉树的创建、遍历、计算等操作。
【实验目的】
递归过程是如何执行的?递归程序该如何编写?――这一直是困惑学生的问题。
通过对二叉树操作的练习,使学生增加对递归过程的感性认识,从而帮助他们理解递归方法,提高编写递归程序的能力。
【基本要求】
(1)创建二叉树
(2)实现对二叉树的先序、中序、后序和按层次遍历
(3)实现对二叉数的各种运算,如结点总数、叶子数、深度、宽度等
(4)实现二叉树的其他操作,如找已知结点的双亲、孩子、兄弟、祖先,复制二叉树等
【实现提示】
(1) 二叉树用二叉链表表示:
BiTNode{
Bitypedef
struct
ElemType data;
*rchild;
struct
BiTNode *lchild,
BiTNode,
*BiTree;
}
(2)创建二叉树可以通过输入能够唯一定义一棵二叉树的序列,如:扩展二叉树的先序序列、
扩展二叉树的后序序列、二叉树的先序序列和中序序列、二叉树的后序序列和中序序列、扩展二叉树的按层次遍历序列等
(3)可以采用多级菜单的操作界面
(4)可以创建多棵二叉树,用一个指针数组来管理这些二叉树的树根指针
【选做内容】
借助于栈,用非递归的方法实现对二叉树的遍历、运算或操作。
实验4:二叉树操作
实验4:二叉树操作(第十三周星期四8-10节)一、实验目的1.学会实现二叉树结点结构和对二叉树的基本操作。
2.掌握对二叉树每种操作的具体实现,学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。
二、实验要求1.认真阅读和掌握和本实验相关的教材内容。
2.编写完整程序完成下面的实验内容并上机运行。
3.整理并上交实验报告。
三、实验内容1.编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归遍历算法(前序、中序、后序)对这棵二叉树进行遍历并计算出二叉树的高度。
2 .编写程序生成下面所示的二叉树,并采用中序遍历的非递归算法对此二叉树进行遍历。
四、源代码、结果:1、#include<iostream.h>#include<stdlib.h>typedef char ElemType;struct BTreeNode {ElemType data;BTreeNode*left;BTreeNode*right;};void InitBTree(BTreeNode*& BT){BT=NULL;}void CreateBTree(BTreeNode*& BT,char*a){const int MaxSize=10;BTreeNode*s[MaxSize];int top=-1;BT=NULL;BTreeNode*p;int k;int i=0;while(a[i]){switch(a[i]){case' ':break;case'(':if(top==MaxSize-1) {cout<<"栈空间太小,请增加MaxSize的值!"<<endl;exit(1);}top++;s[top]=p;k=1;break;case')':if(top==-1) {cout<<"二叉树广义表字符串错!"<<endl;exit(1);}top--;break;case',':k=2;break;default:p=new BTreeNode;p->data=a[i];p->left=p->right=NULL;if(BT==NULL) BT=p;else{if(k==1) s[top]->left=p;else s[top]->right=p;}}i++;}}bool EmptyBTree(BTreeNode*BT){return BT==NULL;}int DepthBTree(BTreeNode*BT){if(BT==NULL)return 0;else{int dep1=DepthBTree(BT->left);int dep2=DepthBTree(BT->right);if(dep1>dep2)return dep1+1;elsereturn dep2+1;}}bool FindBTree(BTreeNode*BT,ElemType& x){if(BT==NULL) return false;else {if(BT->data==x) {x=BT->data; return true;}else {if(FindBTree(BT->left,x)) return true;if(FindBTree(BT->right,x)) return true;return false;}}}void PrintBTree(BTreeNode*BT){if(BT!=NULL) {cout<<BT->data;if(BT->left!=NULL||BT->right!=NULL) {cout<<'(';PrintBTree(BT->left);if(BT->right!=NULL)cout<<',';PrintBTree(BT->right);cout<<')';}}}void ClearBTree(BTreeNode*&BT) {if(BT!=NULL) {ClearBTree(BT->left);ClearBTree(BT->right);delete BT;BT=NULL;}}void PreOrder(BTreeNode*BT) {if(BT!=NULL) {cout<<BT->data<<' ';PreOrder(BT->left);PreOrder(BT->right);}}void InOrder(BTreeNode*BT){if(BT!=NULL) {InOrder(BT->left);cout<<BT->data<<' ';InOrder(BT->right);}}void PostOrder(BTreeNode*BT) {if(BT!=NULL) {PostOrder(BT->left);PostOrder(BT->right);cout<<BT->data<<' ';}}void main(){BTreeNode*bt;InitBTree(bt);char b[50];cout<<"输入二叉树用广义表表示的字符串!"<<endl;cin.getline(b,sizeof(b));CreateBTree(bt,b);PrintBTree(bt);cout<<endl;cout<<"前序:"; PreOrder(bt); cout<<endl;cout<<"中序:"; InOrder(bt); cout<<endl;cout<<"后序:";PostOrder(bt);cout<<endl;ElemType x;cout<<"输入一个待查找字符:";cin>>x;if(FindBTree(bt,x)) cout<<"查找字符"<<x<<"成功"<<endl;else cout<<"查找字符"<<x<<"失败!"<<endl;cout<<"深度: ";cout<<DepthBTree(bt)<<endl;ClearBTree(bt);}运算结果:2、中序非递归遍历:void InOrder(BTreeNode p,SqStack&S){while(S.top!=S.base||p!=NULL){if(p!=NULL) {Push(S,p);p=->lchild;}else{BiTree=Pop(S);if(!PrintElememt(bi->data))cout<<"输出其值未成功!"<<endl;p->bi->rchild;}}cout<<endl;}五、思考与提高1.如何计算二叉链表存储的二叉树中度数为1的结点数?源代码:int Onchild(BiTree T)//单分支节点的{int num1,num2,n=0;if(T==NULL)return(0);elseif((T->lchild==NULL&&T->rchild!=NULL)||(T->lchild!=NULL&&T->rchild==NULL)) n=1;num1=Onchild(T->lchild);num2=Onchild(T->rchild);return(num1+num2+n);}。
二叉树的操作实验报告
二叉树的操作实验报告
实验报告:二叉树的操作
引言:
二叉树是计算机科学中最基础、最重要的数据结构之一,它不仅在算法设计与分析中被广泛应用,而且也在计算机系统和软件工程领域被广泛使用。
在这次实验中,我们将学习和实现二叉树的基本操作,包括二叉树的建立、遍历、查找和删除等。
实验过程:
1. 二叉树的建立
2. 二叉树的遍历
3. 二叉树的查找
4. 二叉树的删除
实验结果:
1. 建立一颗二叉树,根节点为A,左子树B,右子树C,B的左子树D,右子树E,C的左子树F,右子树G。
结构如下:
A
/ \
B C
/ \ / \
D E F G
2. 对上述二叉树先进行中序遍历:DBEAFCG,再进行前序遍历:ABDECFG,最后进行后序遍历:DEBFGCA。
3. 在上述二叉树中查找元素G,并输出其父节点元素C。
4. 删除上述二叉树中的元素F,再对其进行中序遍历,结果为DBEACG。
结论:
通过这次实验,我们掌握了二叉树的基本操作方法,对于理解和分析算法、编写系统和软件工程都具有重要的意义。
同时,在实践中我们也深刻地认识到了二叉树操作的复杂性和局限性,这需要我们在实际应用中加以考虑和综合利用,才能发挥其最大的价值和作用。
实验四、二叉树
实验四二叉树的应用一、实验目的1)了解二叉树的概念、性质。
2)二叉树的存储结构及其遍历。
3)理解应用二叉树的程序。
二、实验内容1)二叉树定义及其性质。
二叉树是一种很重要的数据结构。
其特点是每个结点至多只有两棵子树,一棵称为左子树、另一棵称为右子树。
a、二叉树性质1、二叉树的第i层至多有2^(i-1)个结点(i>=1)。
2、深度为k的二叉树至多有2^k-1个结点(k>=1)。
b、二叉树的两种特殊形式。
1、满二叉树。
它是高为k,且有2^k -1个结点的二叉树。
其特点是每一层上的结点数都是最大结点数。
2、完全二叉树性质1)叶子结点只可能在层次最大的两层上出现。
2)对任意一结点,若其右分支下的子孙的最大层次数为x,则其左分支下的子孙的最大层次数不小于x。
2)二叉树的存储结构和遍历。
3)一般二叉树的链式存储结构三、程序结构、1)链式存储的二叉树的建立#define NULL 0struct link{struct link *lchild;struct link *rchild;char data;};struct link *root;char ch;struct link *newnode(){return((struct link * ) malloc (sizeof(struct link)));}struct link *creattree(){struct link *tree;scanf("%c",&ch);printf("%c",ch);if(ch!='.'){tree=newnode();tree->data=ch;tree->lchild=creattree(); tree->rchild=creattree(); }elsetree=NULL;return(tree);}2)二叉树的遍历a、先序遍历:若二叉树为空,返回;否则,访问根结点,先序遍历左子数,先序遍历右子数。
实验四:二叉树的基本操作和应用
while(1)
{
scanf("%d",&i);
if(i==1)
{
printf("Preorder :");
PreOrder(root);
printf("\n");
}
if(i==2)
{
struct Node * RChild;
}BiTree;
BiTree* BuildTree(BiTree *B)
{
char ch;
ch=getchar();
if(ch=='0')
B=NULL;
else
{
B=(BiTree *)malloc(sizeof(BiTree));
B->data=ch;
B->LChild=BuildTree(B->LChild);
{
PostOrder(root ->LChild);
PostOrder(root ->RChild);
printf("%c",root->data);
}
}
void End(BiTree *root)
{
printf("End");
}
void Set(BiTree *root)
{ int i;
printf("*********************************************\n");
B->RChild=BuildTree(B->RChild);
实验四 二叉树基本操作的实现
实验四二叉树基本操作的实现专业:计算机科学与技术班级:10计本1班学号:姓名:实验地点:B102 实验时间:2011-11-23 指导教师:王润鸿实验目的1 理解二叉树概念及其存储结构;2掌握采用二叉链储存结构的二叉树基本操作;3学会设计实验数据验证程序。
实验环境计算机,window xp操作系统,VC++6.0实验内容1. 存储结构定义:typedef struct BiTNode { //结点定义TElemType data;struct BiTNode * lchild, * rchild;} BiTNode,*BiTree;2. 实现的基本操作:InitBiTree(&T);操作结果:构造空二叉树T。
CreateBiTree(&T, definition);初始条件:definition 给出二叉树T 的定义。
操作结果:按definition 构造二叉树T。
DestroyBiTree(&T);初始条件:二叉树T 存在。
操作结果:销毁二叉树T。
BiTreeEmpty(T);初始条件:二叉树T 存在。
操作结果:若T为空二叉树,则返回TRUE,否则返回FALSE。
BiTreeDepth(T);初始条件:二叉树T 存在。
操作结果:返回T 的深度。
Root(T);初始条件:二叉树T 存在。
操作结果:返回T 的根。
Value(T, e);初始条件:二叉树T 存在,e 是T 中某个结点。
操作结果:返回e 的值。
Parent(T, e);初始条件:二叉树T 存在,e 是T 中某个结点。
操作结果:若e是T的非根结点,则返回它的双亲,否则返回"空"。
LeftChild(T, e);初始条件:二叉树T 存在,e 是T 中某个结点。
操作结果:返回e 的左孩子。
若e 无左孩子,则返回"空"。
RightChild(T, e);初始条件:二叉树T 存在,e 是T 中某个结点。
数据结构二叉树的基本操作
数据结构与算法课程实验报告实验四:二叉树的基本操作姓名:沈靖雯班级:14信息与计算科学(2)班学号:2014326601094实验四二叉树的基本操作【实验内容】实现创建和遍历二叉树的基本操作【实验目的】掌握二叉树的定义和存储表示,学会建立一棵特定二叉树的方法;掌握二叉树的遍历算法(先序、中序、后序遍历算法)的思想,并学会遍历算法的递归实现和非递归实现。
【问题描述】(1)编程实现构造一棵二叉树的算法,适合任意合法输入的二叉树的建立,并进行相应异常处理。
(2)编程实现在二叉链表这种存储方式下,实现二叉的遍历,可采用递归或者非递归实现,遍历算法可在先序、中序和后序遍历算法中任选其一。
【问题实现】一、实现链队列基本运算(1)抽象数据类型ADT BTree {数据对象D: D是具有相同特性的数据元素的集合。
基本操作:CreatBiTree(*T)操作结果:构造二叉树T。
PreOrderTraverse(T)初始条件:二叉树T已存在。
操作结果:先序遍历T。
InOrderTraverse(T)初始条件:二叉树T已存在。
操作结果:中序遍历T。
PostOrderTraverse(T)初始条件:二叉树T已存在。
操作结果:后序遍历T。
} ADT BTree(2)主要实现思路与主要程序代码:1).首先定义二叉树结点结构;typedef struct Node{char data;struct Node *lchild,*rchild; //左右孩子指针}BiTNode,*BTree;2).其次定义一个二叉树构造函数int CreatBiTree(BTree *T);采用递归先序法构造二叉树;scanf("%c",&ch);if(ch==' ')*T=NULL;//T为空二叉树else{if(!(*T=(BTree)malloc(sizeof(BiTNode)))) return (OVERFLOW);(*T)->data=ch;CreatBiTree(&((*T)->lchild));CreatBiTree(&((*T)->rchild));}3).定义遍历函数(递归先序为例);//先序遍历二叉树,递归实现void PreOrderTraverse(BTree T){if(T){ printf("%c ",T->data);PreOrderTraverse (T->lchild);PreOrderTraverse (T->rchild);}}这里用printf代替visit(),简化程序代码;4).定义主函数,总体完成以上所有函数功能的实现(构建二叉树与遍历二叉树)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四二叉树基本操作(4课时)一、实验目的1.掌握二叉树的结构特征,以及各种存储结构的特点及使用范围。
2.掌握用指针类型描述、访问和处理二叉树的运算。
二、实验要求1.设计子函数实现题目要求的功能;2.编译、连接通过,熟练使用命令键;3.运行结果正确,输入输出有提示,格式美观。
三、实验设备、材料和工具1.奔腾2计算机或以上机型2.turboc2,win-tc四、实验内容和步骤实验内容:1.先序输出二叉树的所有结点。
2.求二叉树高度。
3.哈夫曼树及其编码。
五、实验报告要求1.针对程序的健壮性准备好测试数据;2.结果分析中如实填写运行后的结果,并画出二叉树。
六、根据实验过程填写下面内容1.程序及结果:# include <stdio.h>#include <malloc.h>#include <conio.h>#itypedef char DataType;typedef struct Node{DataType data;struct Node *LChild;struct Node *RChild;}BiTNode, *BiTree;void CreateBiTree(BiTree *bt){char ch;ch = getchar();if(ch=='.') *bt=NULL;else{*bt=(BiTree)malloc(sizeof(BiTNode)); //生成一个新结点(*bt)->data=ch;CreateBiTree(&((*bt)->LChild)); //生成左子树CreateBiTree(&((*bt)->RChild)); //生成右子树}}#include "bitree.h"void PreOrder(BiTree root)/*先序遍历二叉树, root为指向二叉树根结点的指针*/{if (root!=NULL){printf("%c ",root ->data); /*输出结点*/PreOrder(root ->LChild); /*先序遍历左子树*/PreOrder(root ->RChild); /*先序遍历右子树*/ }}void main(){BiTree T;printf("按扩展先序遍历序列建立二叉树,请输入序列:\n");CreateBiTree(&T);printf("先序遍历输出序列为:");PreOrder(T);getch();}#include <stdio.h>#include <malloc.h>#include <conio.h>typedef int DataType;typedef struct NodeDataType data;struct Node *LChild;struct Node *RChild;}BiTNode, *BiTree;void CreateBiTree(BiTree *bt){int ch;ch = getint();if(ch=='-1') *bt=NULL;else{*bt=(BiTree)malloc(sizeof(BiTNode)); //生成一个新结点(*bt)->data=ch;CreateBiTree(&((*bt)->LChild)); //生成左子树CreateBiTree(&((*bt)->RChild)); //生成右子树}}#include "bitree.h"void PreOrder(BiTree root)/*先序遍历二叉树, root为指向二叉树根结点的指针*/{if (root!=NULL){printf("%d ",root ->data); /*输出结点*/PreOrder(root ->LChild); /*先序遍历左子树*/PreOrder(root ->RChild); /*先序遍历右子树*/ }}void main(){BiTree T;printf("按扩展先序遍历序列建立二叉树,请输入序列:\n");CreateBiTree(&T);printf("先序遍历输出序列为:");PreOrder(T);getch();}2.程序#include "bitree.h"int PostTreeDepth(BiTree bt) /* 后序遍历求二叉树的高度递归算法*/ {int hl,hr,max;if(bt!=NULL){hl=PostTreeDepth(bt->LChild); /* 求左子树的深度*/hr=PostTreeDepth(bt->RChild); /* 求右子树的深度*/max=hl>hr?hl:hr; /* 得到左、右子树深度较大者*/return(max+1); /* 返回树的深度*/ }else return(0); /* 如果是空树,则返回0 */}void main(){BiTree T;int h;printf("按扩展先序遍历序列建立二叉树,请输入序列:\n");CreateBiTree(&T);h = PostTreeDepth(T);printf("The depth of this tree is:%d\n",h);getch();}结果:3.程序及结果:#include <stdio.h>#include <stdlib.h>#include <string.h>typedef char* HuffmanCode;/*动态分配数组,存储哈夫曼编码*/typedef struct{unsigned int weight ; /* 用来存放各个结点的权值*/unsigned int parent, LChild,RChild ; /*指向双亲、孩子结点的指针*/ }HTNode, * HuffmanTree; /*动态分配数组,存储哈夫曼树*/void select(HuffmanTree *ht,int n, int *s1, int *s2){int i;int min;for(i=1; i<=n; i++){if((*ht)[i].parent == 0){min = i;i = n+1;}}for(i=1; i<=n; i++){if((*ht)[i].parent == 0){if((*ht)[i].weight < (*ht)[min].weight)min = i;}}*s1 = min;for(i=1; i<=n; i++){if((*ht)[i].parent == 0 && i!=(*s1)){min = i;i = n+1;}}for(i=1; i<=n; i++){if((*ht)[i].parent == 0 && i!=(*s1)){if((*ht)[i].weight < (*ht)[min].weight)min = i;}}*s2 = min;}void CrtHuffmanTree(HuffmanTree *ht , int *w, int n){ /* w存放已知的n个权值,构造哈夫曼树ht */int m,i;int s1,s2;m=2*n-1;*ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); /*0号单元未使用*/for(i=1;i<=n;i++){/*1-n号放叶子结点,初始化*/(*ht)[i].weight = w[i];(*ht)[i].LChild = 0;(*ht)[i].parent = 0;(*ht)[i].RChild = 0;}for(i=n+1;i<=m;i++){(*ht)[i].weight = 0;(*ht)[i].LChild = 0;(*ht)[i].parent = 0;(*ht)[i].RChild = 0;} /*非叶子结点初始化*//* ------------初始化完毕!对应算法步骤1---------*/for(i=n+1;i<=m;i++) /*创建非叶子结点,建哈夫曼树*/{ /*在(*ht)[1]~(*ht)[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2返回*/select(ht,i-1,&s1,&s2);(*ht)[s1].parent=i;(*ht)[s2].parent=i;(*ht)[i].LChild=s1;(*ht)[i].RChild=s2;(*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight;}}/*哈夫曼树建立完毕*/void outputHuffman(HuffmanTree HT, int m){if(m!=0){printf("%d ", HT[m].weight);outputHuffman(HT,HT[m].LChild);outputHuffman(HT,HT[m].RChild);}}void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n)/*从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码*/{char *cd;int i;unsigned int c;int start;int p;hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); /*分配n个编码的头指针*/cd=(char * )malloc(n * sizeof(char )); /*分配求当前编码的工作空间*/cd[n-1]='\0'; /*从右向左逐位存放编码,首先存放编码结束符*/for(i=1;i<=n;i++) /*求n个叶子结点对应的哈夫曼编码*/{start=n-1; /*初始化编码起始指针*/for(c=i,p=(*ht)[i].parent; p!=0; c=p,p=(*ht)[p].parent) /*从叶子到根结点求编码*/ if( (*ht)[p].LChild == c)cd[--start]='0'; /*左分支标0*/elsecd[--start]='1'; /*右分支标1*/hc[i]=(char *)malloc((n-start)*sizeof(char)); /*为第i个编码分配空间*/strcpy(hc[i],&cd[start]);}free(cd);for(i=1;i<=n;i++)printf("%d编码为%s\n",(*ht)[i].weight,hc[i]);}void main(){HuffmanTree HT;HuffmanCode HC;int *w;int i,n; // the number of elements;int wei; // the weight of a element;int m;printf("input the total number of the Huffman Tree:" );scanf("%d",&n);w=(int *)malloc((n+1)*sizeof(int));for(i=1;i<=n;i++){printf("input the %d element's weight:",i);fflush(stdin);scanf("%d",&wei);w[i]=wei;}CrtHuffmanTree(&HT,w,n);m = 2*n-1;outputHuffman(HT,m);printf("\n");CrtHuffmanCode(&HT,&HC,n); }。