实验三 二叉树的基本运算

合集下载

实验报告二叉树

实验报告二叉树
p->data);PreOrder(p->lchild);PreOrder(p->rchild);}}void InOrder(BiTree p){ /* 中序遍历二叉树*/ if( p!= NULL ) {InOrder( p->lchild ) ;printf("%c", p->data);InOrder( p->rchild) ; } }void PostOrder(BiTree p){ /* 后序遍历二叉树*/ if ( p!= NULL ) {PostOrder( p->lchild ) ;PostOrder( p->rchild) ;printf("%c", p->data); } }void Preorder_n(BiTree p){ /*先序遍历的非递归算法*/ BiTree stack[MAX],q; int top=0,i;for(i=0;i while(q!=NULL){printf("%c",q->data);if(q->rchild!=NULL) stack[top++]=q->rchild;if(q->lchild!=NULL) q=q->lchild;elseif(top>0) q=stack[--top]; else q=NULL; } }void release(BiTree t){ /*释放二叉树空间*/ if(t!=NULL){release(t->lchild); release(t->rchild);
递归遍历右子树输出根结点数data}void postOrder1 (struct btnode *bt){概念栈,结点参数p,prebt入栈While(栈或p是不是为空){提取栈顶元素值if判定p是不是为空或是pre的根结点输出根结点数data栈顶元素出栈栈顶元素p赋给pre记录else if右结点非空将右结点压栈if左结点将左结点压栈}}void main(){struct btnode *root=NULL;root=createbt(root);preOrder(root); midOrder(root); postOrder(root);preOrder1(root); midOrder1(root); postOrder1(root);

二叉树基本运算

二叉树基本运算

二叉树基本运算二叉树基本运算二叉树是计算机科学中最基础的数据结构之一,它由节点和指向其左右子节点的指针组成。

在实际应用中,二叉树作为一种重要的数据结构,可以用于解决各种问题。

在进行二叉树的操作时,常见的有插入节点、删除节点、查找节点以及遍历。

这些操作都是二叉树的基本运算。

第一类运算是插入节点的操作。

插入节点到二叉树中,需要根据一定的规则将新节点放置在合适的位置。

例如,若新节点的值比当前节点的值小,则将其放在当前节点的左侧;若新节点的值大,则将其放在当前节点的右侧。

这样,可以保持二叉树的有序性。

插入节点的运算可以通过递归或迭代的方式实现。

无论是哪种方式,重要的是要保证插入后的二叉树仍然是一棵二叉树。

第二类运算是删除节点的操作。

删除节点的操作相对比较复杂,需要考虑被删除节点的子节点情况。

若被删除节点没有子节点,则直接删除即可;若被删除节点只有一个子节点,则将其子节点连接到被删除节点的父节点上即可;若被删除节点有两个子节点,则需找到其右子树的最小节点,用该最小节点替代被删除节点,并删除该最小节点。

删除节点的运算同样可以通过递归或迭代的方式实现。

第三类运算是查找节点的操作。

查找节点的操作可以用于判断二叉树中是否存在某个特定值的节点。

查找节点的运算可以通过递归或迭代的方式实现。

在递归实现中,从根节点开始,若当前节点的值等于目标值,则返回该节点,否则分别在左子节点和右子节点中进行查找。

在迭代实现中,可以借助栈或队列等数据结构来辅助查找。

最后一类运算是遍历二叉树的操作。

二叉树的遍历有三种方式:前序遍历、中序遍历和后序遍历。

前序遍历先访问根节点,然后依次遍历左子树和右子树;中序遍历先遍历左子树,然后访问根节点,最后遍历右子树;后序遍历先遍历左子树,然后遍历右子树,最后访问根节点。

这三种遍历方式均可以通过递归或迭代的方式实现。

在二叉树的基本运算中,不同的操作可以根据具体的需求进行选择。

其中,插入节点、删除节点和查找节点操作都涉及到对二叉树结构的修改,需要小心处理,以保证操作的正确性。

二叉树的定义及基本操作

二叉树的定义及基本操作
五、实验结果及分析
(所输入的数据及相应的运行结果,运行结果要有提示信息,运行结果采用截图 方式给出。)
2
① 输入界面
②输出结果
③测试式子 6*((5+(2+)*8)+3)
六、总结与体会
(调试程序的心得与体会,若实验课上未完成调试,要认真找出错误并分析原因 等。)
每次的实验,总是很受打击。不过,在这过程中,能让我发现自己的 不足,逐渐改善,这是做实验给我最大的收获。 七、程序清单(包含注释)
四、实验记录
(调试过程及调试中遇到的问题及解决办法,其他算法的存在与实践等。) ① 调试过程老是出现访问冲突的错问,通过上网查找访问冲突方面的消息,才
知道应该是指针指错地址,经过调试,最终解决了问题。 ②
调试过程中还出现了这个问题,Status CreateBiTree(BiTree T),当这样定 义时,问题就出现了,但是 Status CreateBiTree(BiTree &T)这样定义就没问题 了,这个想不通。
-
+
/
1.中缀表达式(中序遍历): a+(b*(c-d))-(e/f)
a
*e
2.前缀表达式/波兰式(前序遍历):
f
-+a*b-cd/ef
b-
3.后缀表达式/逆波兰式(后序遍历): abcd-*+ef/-
《《《《《
《 《《《《
C《《《 《 P129
cd
表达式二叉树
1
三、实验所涉及的知识点 递归函数 二叉树
输入说明
***\n"); printf("*** 请按先序输入表达式,当结点的左子树或者右
子树为空时输入‘#‘***\n");

实验三--二叉树的基本运算

实验三--二叉树的基本运算

实验三二叉树的基本运算一、实验目的1、使学生熟练掌握二叉树的逻辑结构和存储结构。

2、熟练掌握二叉树的各种遍历算法。

二、实验内容1、问题描述建立一棵二叉树,试编程实现二叉树的如下基本操作:(1). 按先序序列构造一棵二叉链表表示的二叉树T;(2). 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列;(3). 求二叉树的深度/结点数目/叶结点数目;(选做)(4). 将二叉树每个结点的左右子树交换位置。

(选做)2、基本要求从键盘接受输入(先序),以二叉链表作为存储结构,建立二叉树(以先序来建立)。

3、测试数据如输入:abc00de0g00f000(其中ф表示空格字符)则输出结果为:先序:a->b->c->d->e->g->f中序:a->b->c->d->e->g->f后序:a->b->c->d->e->g->f三、程序代码#include<malloc.h>#include<iostream.h>#define OK 1#define ERROR -1typedef char TElemType;int i;typedef struct BiTNode{TElemType data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;int CreateBiTree(BiTree&T) //创建二叉树{char a;cin>>a;if(a=='0') T=NULL;else{if(!(T=(BiTNode*)malloc(sizeof(BiTNode)))) {return ERROR;}T->data=a;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}return OK;}int PreOrderTraverse(BiTree&T) //先序遍历二叉树{if(T){//cout<<"此为先序遍历"<<endl;cout<<T->data<<"->";if(PreOrderTraverse(T->lchild))if(PreOrderTraverse(T->rchild))return OK;return ERROR;}else return OK;}int InOrderTraverse(BiTree&T) //中序遍历二叉树{if(T){//cout<<"此为中序遍历"<<endl;if(InOrderTraverse(T->lchild)){cout<<T->data<<"->";if(InOrderTraverse(T->rchild))return OK;}return ERROR;}else return OK;}int PostOrderTraverse(BiTree&T) //后序遍历二叉树{if(T){//cout<<"此为后序遍历"<<endl;if (PostOrderTraverse(T->lchild))if(PostOrderTraverse(T->rchild)){cout<<T->data<<"->";i++;return (OK);}return (ERROR);}elsereturn (OK);}int CountDepth(BiTree&T) //计算二叉树的深度{if(T==NULL){return 0;}else{int depl=CountDepth(T->lchild);int depr=CountDepth(T->lchild);if(depl>depr){return depl+1;}else{return depr+1;}}}void main() //主函数{BiTree T;cout<<"请输入二叉树节点的值以创建树"<<endl;CreateBiTree(T);cout<<"此为先序遍历";PreOrderTraverse(T);cout<<"end"<<endl;cout<<"此为中序遍历";InOrderTraverse(T);cout<<"end"<<endl;cout<<"此为后序遍历";PostOrderTraverse(T);cout<<"end"<<endl<<"此树节点数是"<<i<<endl<<"此树深度是"<<CountDepth(T)<<endl;}四、调试结果及运行界面:五、实验心得通过这次程序上机实验让我认识到了以前还不太了解的二叉树的性质和作用,这次实验的的确确的加深了我对它的理解。

数据结构实验三实验报告

数据结构实验三实验报告

数据结构实验三实验报告数据结构实验三实验报告一、实验目的本次实验的目的是通过实践掌握树的基本操作和应用。

具体来说,我们需要实现一个树的数据结构,并对其进行插入、删除、查找等操作,同时还需要实现树的遍历算法,包括先序、中序和后序遍历。

二、实验原理树是一种非线性的数据结构,由结点和边组成。

树的每个结点都可以有多个子结点,但是每个结点只有一个父结点,除了根结点外。

树的基本操作包括插入、删除和查找。

在本次实验中,我们采用二叉树作为实现树的数据结构。

二叉树是一种特殊的树,每个结点最多只有两个子结点。

根据二叉树的特点,我们可以使用递归的方式实现树的插入、删除和查找操作。

三、实验过程1. 实现树的数据结构首先,我们需要定义树的结点类,包括结点值、左子结点和右子结点。

然后,我们可以定义树的类,包括根结点和相应的操作方法,如插入、删除和查找。

2. 实现插入操作插入操作是将一个新的结点添加到树中的过程。

我们可以通过递归的方式实现插入操作。

具体来说,如果要插入的值小于当前结点的值,则将其插入到左子树中;如果要插入的值大于当前结点的值,则将其插入到右子树中。

如果当前结点为空,则将新的结点作为当前结点。

3. 实现删除操作删除操作是将指定的结点从树中移除的过程。

我们同样可以通过递归的方式实现删除操作。

具体来说,如果要删除的值小于当前结点的值,则在左子树中继续查找;如果要删除的值大于当前结点的值,则在右子树中继续查找。

如果要删除的值等于当前结点的值,则有三种情况:- 当前结点没有子结点:直接将当前结点置为空。

- 当前结点只有一个子结点:将当前结点的子结点替代当前结点。

- 当前结点有两个子结点:找到当前结点右子树中的最小值,将其替代当前结点,并在右子树中删除该最小值。

4. 实现查找操作查找操作是在树中寻找指定值的过程。

同样可以通过递归的方式实现查找操作。

具体来说,如果要查找的值小于当前结点的值,则在左子树中继续查找;如果要查找的值大于当前结点的值,则在右子树中继续查找。

二叉树的操作实验报告

二叉树的操作实验报告

二叉树的操作实验报告二叉树的操作实验报告引言二叉树是计算机科学中常用的数据结构,它具有良好的搜索性能和灵活的插入和删除操作。

本实验旨在通过实际操作,深入理解二叉树的基本操作和特性。

1. 二叉树的定义和基本概念二叉树是一种特殊的树状结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。

二叉树的节点由数据和指向左右子节点的指针组成。

根据节点的位置,可以将二叉树分为左子树、右子树和根节点。

2. 二叉树的遍历二叉树的遍历是指按照一定的顺序访问二叉树中的所有节点。

常用的遍历方式有前序遍历、中序遍历和后序遍历。

前序遍历先访问根节点,然后按照左子树、右子树的顺序遍历;中序遍历先访问左子树,然后根节点,最后右子树;后序遍历先访问左子树,然后右子树,最后根节点。

3. 二叉树的插入操作插入操作是将一个新节点插入到二叉树中的特定位置。

插入操作需要考虑节点的大小关系,小于当前节点则插入到左子树,大于当前节点则插入到右子树。

插入操作可以保持二叉树的有序性。

4. 二叉树的删除操作删除操作是将指定节点从二叉树中删除。

删除操作需要考虑被删除节点的子节点情况,如果被删除节点没有子节点,则直接删除;如果有一个子节点,则将子节点替代被删除节点的位置;如果有两个子节点,则选择被删除节点的后继节点或前驱节点替代被删除节点。

5. 二叉树的查找操作查找操作是在二叉树中搜索指定的节点。

二叉树的查找操作可以使用递归或迭代的方式实现。

递归方式会自动遍历整个二叉树,直到找到目标节点或遍历完整个树。

迭代方式则需要手动比较节点的值,并根据大小关系选择左子树或右子树进行进一步查找。

6. 二叉树的平衡性二叉树的平衡性是指左子树和右子树的高度差不超过1。

平衡二叉树可以提高搜索效率,避免出现极端情况下的性能下降。

常见的平衡二叉树有AVL树和红黑树。

7. 二叉树应用场景二叉树在计算机科学中有广泛的应用场景。

例如,文件系统的目录结构可以使用二叉树来表示;数据库中的索引结构也可以使用二叉树来实现。

实现二叉树的各种基本运算的算法

实现二叉树的各种基本运算的算法

实现二叉树的各种基本运算的算法1.二叉树的定义及概述二叉树是一种重要的数据结构,它是由节点组成的序列,每个节点最多有两个子节点。

二叉树的根节点是唯一的,且每个节点都有一个“父节点”,除了根节点外,每个子节点称作“左孩子”和“右孩子”。

二叉树的组成部分是节点,每个节点包括一个数据元素和左右孩子指针。

通过这些指针构成的树形结构,可以便捷地进行数据存储和操作。

本文将介绍二叉树的各种基本运算及实现方法。

2.二叉树的遍历二叉树的遍历分为三种:前序遍历、中序遍历和后序遍历。

前序遍历:按照“根节点-左孩子-右孩子”的顺序遍历二叉树。

中序遍历:按照“左孩子-根节点-右孩子”的顺序遍历二叉树。

后序遍历:按照“左孩子-右孩子-根节点”的顺序遍历二叉树。

3.二叉树的建立二叉树的建立有三种方法:链式存储法、顺序存储法和扩展二叉树。

链式存储法:链式存储法是用链表来表示二叉树的方法,每个节点包括数据域和左右孩子指针域。

链式存储法建立二叉树比较容易,操作起来也比较方便。

顺序存储法:顺序存储法是用数组来表示二叉树的方法,便于存取、操作和查找。

但是顺序存储法的空间利用率不高,只有满二叉树才能利用完全。

扩展二叉树:是指二叉树中所有的空节点都必须存储起来,以构成一颗可以存储不满的二叉树。

由于扩展二叉树浪费了大量的空间,因此很少使用。

4.二叉树的查找二叉树的查找分为两种:层序遍历和二叉排序树的查找。

层序遍历:是一种广度优先搜索的方式来遍历二叉树。

层序遍历可以找到二叉树中从根节点到任意节点的路径,具有较高的效率。

层序遍历可以使用队列来实现。

二叉排序树的查找:是指在一颗二叉排序树中查找某个元素的算法。

二叉排序树(BST)是一颗二叉树,其中每个节点的值都比它的左子节点大,比它的右子节点小。

通过对BST的查找操作,可以将查找的效率高效地进行。

5.二叉树的删除在二叉树中删除节点有两种情况:删除叶子节点和删除非叶子节点。

下面给出二叉树的删除基本操作。

二叉树的各种基本运算的实现实验报告

二叉树的各种基本运算的实现实验报告

二叉树的各种基本运算的实现实验报告
一、实验目的
实验目的为了深入学习二叉树的各种基本运算,通过操作实现二叉树的建立、存储、查找、删除、遍历等各种基本运算操作。

二、实验内容
1、构造一个二叉树。

我们首先用一定的节点来构建一棵二叉树,包括节点的左子节点和右子节点。

2、实现查找二叉树中的节点。

在查找二叉树中的节点时,我们根据二叉树的特点,从根节点开始查找,根据要查找的节点的值与根节点的值的大小的关系,来决定接下来查找的方向,直到找到要查找的节点为止。

3、实现删除二叉树中的节点。

在删除二叉树节点时,我们要做的是找到要删除节点的父节点,然后让父节点的链接指向要删除节点的子节点,有可能要删除节点有一个子节点,有可能有两个极点,有可能没有子节点,我们要根据每种情况进行处理,来保持二叉树的结构不变。

4、对二叉树进行遍历操作。

二叉树的遍历有多种方法,本实验使用的是先序遍历。

首先从根节点出发,根据先序遍历的顺序,先访问左子树,然后再访问右子树,最后访问根节点。

三、实验步骤
1、构建二叉树:
我们用一个数组代表要构建的二叉树,第一项为根节点,第二项和第三项是根节点的子节点。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验三二叉树的基本运算
一、实验目的
1、使学生熟练掌握二叉树的逻辑结构和存储结构。

2、熟练掌握二叉树的各种遍历算法。

二、实验内容
[问题描述]
建立一棵二叉树,试编程实现二叉树的如下基本操作:
1. 按先序序列构造一棵二叉链表表示的二叉树T;
2. 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列;
3. 求二叉树的深度/结点数目/叶结点数目;(选做)
4. 将二叉树每个结点的左右子树交换位置。

(选做)
[基本要求]
从键盘接受输入(先序),以二叉链表作为存储结构,建立二叉树(以先序来建立),
[测试数据]
如输入:ABCффDEфGффFффф(其中ф表示空格字符)
则输出结果为
先序:ABCDEGF
中序:CBEGDFA
后序:CGEFDBA
层序:ABCDEFG
[选作内容]
采用非递归算法实现二叉树遍历。

三、实验程序
#include <iostream>
#include <math.h>
using namespace std;
typedef char TElemType;
typedef struct BiTNode{ //定
义节点
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int DLRcreat(BiTree &T) //先序建立二叉树
{
char d;
cin>>d;
if(d=='#')T=NULL;
else
{
T=new BiTNode;
if(!T)exit(1);
T->data=d;
DLRcreat(T->lchild);
DLRcreat(T->rchild);
}
return 0;
}
int florder(BiTree T) //
层序遍历指针数组
{
BiTNode *Q[100]; //树节点指针数组,用于存放遍历到的元素地址
if(T==NULL)cout<<"空的二叉树"<<endl;
Q[0]=T; //存入树根
int i;
int j=1;
for(i=0;i<j;i++)
{
if(Q[i]->lchild!=NULL) //如果有左孩子,存入地址,j加一,否则没操作
{
Q[j]=Q[i]->lchild ;
j++;
}
if(Q[i]->rchild!=NULL) //如果有右孩子,存入地址,j加一,否则没操作
{
Q[j]=Q[i]->rchild ;
j++;
}
for(i=0;i<j;i++)cout<<" "<<Q[i]->data;
return 0;
}
int howmuch(BiTree T,int h)
{
BiTNode *Q[100]; //树节点指针数组,用于存放遍历到的元素地址
if(T==NULL)cout<<"空的二叉树"<<endl;
Q[0]=T; //存入树根
int i,k=0;
int j=1; //j-1为总节点
for(i=0;i<j;i++)
{
if(Q[i]->lchild!=NULL) //如果有左孩子,存入地址,j加一,否则没操作
{
Q[j]=Q[i]->lchild ;
j++;
if(Q[i]->rchild!=NULL) //如果
有右孩子,存入地址,j加一,否则没操作
{
Q[j]=Q[i]->rchild ;
j++;
}
if(Q[i]->lchild==NULL&&Q[i]->rchild==NULL)k++; //计算叶子数
}
i=ceil(log(j-1))+1; //计算深度
if(h==0)return j;
else if(h==1)return k;
else if(h==2)return i;
else {cout<<"参数错误";}
return 0;
}
int DLRorder(BiTree T) //先序遍历
{
if(T != NULL)
{
cout<<" "<<T->data; // 访问根结点
DLRorder(T->lchild); // 前序遍历左子树
DLRorder(T->rchild); // 前序遍历右子树
}
return 0;
}
int LDRorder(BiTree T) //中序遍历递归
{
if(T!=NULL)
{
LDRorder(T->lchild);
cout<<" "<<T->data;
LDRorder(T->rchild );
}
return 0;
}
int LRDorder(BiTree T)
//后序遍历递归
{
if(T!=NULL)
{
LDRorder(T->lchild);
LDRorder(T->rchild );
cout<<" "<<T->data;
}
return 0;
}
int exchang(BiTree &T) //交换左右子树
{
if(T != NULL)
{
if(T->lchild!=NULL&&T->rchild!=NULL)
//当有左右孩子时才交换
{
char t;
t=T->lchild->data;T->lchild->data=T->rchild->data;
T->rchild->data=t;
//交换数据
}
exchang(T->lchild);
// 递归调用
exchang(T->rchild);
}
return 0;
}
int choose(BiTree T) //功能选择
{
int a;cin>>a;
if(a==1){cout<<"先序遍历";DLRorder(T);}
else if(a==2){cout<<"中序遍历";LDRorder(T);}
else if(a==3){cout<<"后序遍历";LRDorder(T);}
else if(a==4){cout<<"层序遍历";florder(T);}
else if(a==5){cout<<"总节点数:"<<howmuch(T,0);}
else if(a==6){cout<<"总叶子数:"<<howmuch(T,1);}
else if(a==7){cout<<"树的深度:"<<howmuch(T,2);}
else if(a==8){cout<<"交换前
"<<endl;florder(T);exchang(T);cout<<"交换后
";florder(T);}
else if(a==9)exit(1);
else cout<<"没有这个操作"<<endl;
cout<<endl<<"操作完成,请输入下一个操作"<<endl;
choose(T);
return 0;
}
int main() //主函数
{
cout<<"----------------二叉树的基本操作
----------------"<<endl;
cout<<"请先建立二叉树,按先序的方式输入如果数据为空
输入#"<<endl;
BiTree T; //定义二叉树,初始化
DLRcreat(T);
cout<<"1.先序遍历二叉树 2.中序遍历二
叉树"<<endl;
cout<<"3.后序遍历二叉树 4.层序遍历二
叉树"<<endl;
cout<<"5.求总节点数 6.求叶子总数
"<<endl;
cout<<"7.深度-完全二叉树有效 8.左右子树交换"<<endl;
cout<<"9.退出"<<endl;
choose(T);
return 0;
}
四、实验过程及结果截图。

相关文档
最新文档