二叉树的基本操作及其应用

合集下载

二叉树的基本操作

二叉树的基本操作

二叉树的基本操作二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。

二叉树在计算机领域中得到广泛应用,它的基本操作包括插入、删除、查找、遍历等。

1.插入操作:二叉树的插入操作是将一个新的节点添加到已有的二叉树中的过程。

插入操作会按照一定规则将新节点放置在正确的位置上。

插入操作的具体步骤如下:-首先,从根节点开始,比较新节点的值与当前节点的值的大小关系。

-如果新节点的值小于当前节点的值,则将新节点插入到当前节点的左子树中。

-如果新节点的值大于当前节点的值,则将新节点插入到当前节点的右子树中。

-如果当前节点的左子树或右子树为空,则直接将新节点插入到该位置上。

-如果当前节点的左子树和右子树都不为空,则递归地对左子树或右子树进行插入操作。

2.删除操作:二叉树的删除操作是将指定节点从二叉树中删除的过程。

删除操作有以下几种情况需要考虑:-如果待删除节点是叶子节点,则直接将其从二叉树中删除即可。

-如果待删除节点只有一个子节点,则将其子节点替换为待删除节点的位置即可。

-如果待删除节点有两个子节点,则需要找到其左子树或右子树中的最大节点或最小节点,将其值替换为待删除节点的值,然后再删除最大节点或最小节点。

3.查找操作:二叉树的查找操作是在二叉树中查找指定值的节点的过程。

查找操作的具体步骤如下:-从根节点开始,将待查找值与当前节点的值进行比较。

-如果待查找值等于当前节点的值,则返回该节点。

-如果待查找值小于当前节点的值,则在当前节点的左子树中继续查找。

-如果待查找值大于当前节点的值,则在当前节点的右子树中继续查找。

-如果左子树或右子树为空,则说明在二叉树中找不到该值。

4.遍历操作:二叉树的遍历操作是按照一定规则依次访问二叉树中的每个节点。

有三种常用的遍历方式:- 前序遍历(Preorder Traversal):先访问根节点,然后递归地前序遍历左子树和右子树。

- 中序遍历(Inorder Traversal):先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。

二叉树基本运算

二叉树基本运算

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

二叉树的基本操作课件浙教版(2019)高中信息技术选修1(24张PPT)

二叉树的基本操作课件浙教版(2019)高中信息技术选修1(24张PPT)
如下图所示的是二叉树及其对应的二叉链表实现示意图。
A
B
D
C
E
F
G
头指针
二叉树的list实现
二叉树节点可以看成是一个三元组,元素是左、右子树和本节点数据。
Python的list可以用于组合这样的三个元素。
下面介绍用list构造二叉树的方法。
(1)空树用None表示。
(2)非空二叉树用包含三个元素的列表[d,l,r]表示,其中:d表示根节点的元素,l和r是两棵子树,采用与整个二叉树同样结构的list表示。
二叉树的遍历
在完成二叉树的建立操作后,就可以对二叉树的各个节点进行访问,即遍历操作。二叉树的遍历,是指按照一定的规则和次序访问二叉树中的所有节点,使得每个节点都被访问一次且仅被访问一次。按照不同的遍历方式对节点进行访问,其处理效率不完全相同。二叉树的遍历方式有很多,主要有前序遍历、中序遍历和后序遍历等。
1.数组实现
用数组来表示二叉树时,分为以下两种情况。
(1)完全二叉树从二叉树的根节点开始,按从上而下、自左向右的顺序对n个节点进行编号,根节点的编号为0,最后一个节点的编号为n-1。然后依次将二叉树的节点用一组连续的数组元素来表示,节点编号与数组的下标一一对应。如下图中图甲所示的完全二叉树所对应的一维数组表示如图乙所示。
A
B
C
A
B
C
甲 原二叉树
乙 补全后的二叉树
0
1
2
3
4
5
6
7
丙 数组实现示意图
A
B
C
对于完全二叉树而言,一维数组的表示方式既简单又节省存储空间。但对于一般的二叉树来说,采用一维数组表示时,结构虽然简单,却容易造成存储空间的浪费。

二叉树的建立与基本操作

二叉树的建立与基本操作

二叉树的建立与基本操作二叉树是一种特殊的树形结构,它由节点(node)组成,每个节点最多有两个子节点。

二叉树的基本操作包括建立二叉树、遍历二叉树、查找二叉树节点、插入和删除节点等。

本文将详细介绍二叉树的建立和基本操作,并给出相应的代码示例。

一、建立二叉树建立二叉树有多种方法,包括使用数组、链表和前序、中序、后序遍历等。

下面以使用链表的方式来建立二叉树为例。

1.定义二叉树节点类首先,定义一个二叉树节点的类,包含节点值、左子节点和右子节点三个属性。

```pythonclass Node:def __init__(self, value):self.value = valueself.left = Noneself.right = None```2.建立二叉树使用递归的方法来建立二叉树,先构造根节点,然后递归地构造左子树和右子树。

```pythondef build_binary_tree(lst):if not lst: # 如果 lst 为空,则返回 Nonereturn Nonemid = len(lst) // 2 # 取 lst 的中间元素作为根节点的值root = Node(lst[mid])root.left = build_binary_tree(lst[:mid]) # 递归构造左子树root.right = build_binary_tree(lst[mid+1:]) # 递归构造右子树return root```下面是建立二叉树的示例代码:```pythonlst = [1, 2, 3, 4, 5, 6, 7]root = build_binary_tree(lst)```二、遍历二叉树遍历二叉树是指按照其中一规则访问二叉树的所有节点,常见的遍历方式有前序遍历、中序遍历和后序遍历。

1.前序遍历前序遍历是指先访问根节点,然后访问左子节点,最后访问右子节点。

```pythondef pre_order_traversal(root):if root:print(root.value) # 先访问根节点pre_order_traversal(root.left) # 递归访问左子树pre_order_traversal(root.right) # 递归访问右子树```2.中序遍历中序遍历是指先访问左子节点,然后访问根节点,最后访问右子节点。

二叉树的存储结构及基本操作

二叉树的存储结构及基本操作

二叉树的存储结构及基本操作二叉树是一种常见的数据结构,广泛应用于计算机科学领域。

二叉树具有其独特的存储结构和基本操作,下面将详细介绍。

一、二叉树的存储结构二叉树的存储结构通常有两种形式:顺序存储和链式存储。

1. 顺序存储顺序存储是将二叉树中的所有元素按照一定的顺序存储在一段连续的内存单元中,通常采用数组来表示。

对于任意一个节点i,其左孩子节点的位置为2*i+1,右孩子节点的位置为2*i+2。

这种存储方式的优点是访问速度快,但需要预先确定节点总数,且不易于插入和删除操作。

2. 链式存储链式存储是采用指针的方式将二叉树的节点链接起来。

每个节点包含数据元素以及指向左孩子节点和右孩子节点的指针。

链式存储方式的优点是易于插入和删除操作,但访问速度较慢。

二、二叉树的基本操作1. 创建二叉树创建二叉树的过程就是将数据元素按照一定的顺序插入到二叉树中。

对于顺序存储的二叉树,需要预先分配内存空间;对于链式存储的二叉树,可以直接创建节点对象并链接起来。

2. 遍历二叉树遍历二叉树是指按照某种规律访问二叉树中的所有节点,通常有前序遍历、中序遍历和后序遍历三种方式。

前序遍历的顺序是根节点-左孩子节点-右孩子节点;中序遍历的顺序是左孩子节点-根节点-右孩子节点;后序遍历的顺序是左孩子节点-右孩子节点-根节点。

对于顺序存储的二叉树,可以采用循环结构实现遍历;对于链式存储的二叉树,需要使用指针逐个访问节点。

3. 查找元素在二叉树中查找元素,需要根据一定的规则搜索所有节点,直到找到目标元素或搜索范围为空。

对于顺序存储的二叉树,可以采用线性查找算法;对于链式存储的二叉树,可以采用深度优先搜索或广度优先搜索算法。

4. 插入元素在二叉树中插入元素需要遵循一定的规则,保证二叉树的性质。

对于顺序存储的二叉树,插入操作需要移动大量元素;对于链式存储的二叉树,插入操作相对简单,只需修改指针即可。

5. 删除元素在二叉树中删除元素同样需要遵循一定的规则,保证二叉树的性质。

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

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

实验三二叉树的基本运算一、实验目的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. 左子节点:2i+1(i为父节点的在数组中的下标)
2. 右子节点:2i+2
3. 父节点:(i-1)/2(i为子节点在数组中的下标)
二、基本操作:
1. 创建二叉树:按照上述公式将节点存储到数组中。

2. 遍历二叉树:可采用递归或非递归方式,进行前序、中序、后序、层次遍历。

3. 插入节点:先将节点插入到数组末尾,然后通过比较节点和其父节点的大小,进行上浮操作直到满足二叉树的性质。

4. 删除节点:先将待删除节点和最后一个节点交换位置,然后通过比较交换后的节点和其父节点的大小,进行下沉操作直到满足二
叉树的性质。

5. 查找节点:根据节点值进行查找,可采用递归或非递归方式。

6. 修改节点:根据节点值进行查找,然后进行修改操作。

数据结构二叉树实验报告

数据结构二叉树实验报告

数据结构二叉树实验报告二叉树是一种常用的数据结构,它在计算机科学中有着广泛的应用。

本文将介绍二叉树的定义、基本操作以及一些常见的应用场景。

一、二叉树的定义和基本操作二叉树是一种特殊的树形结构,它的每个节点最多有两个子节点。

一个节点的左子节点称为左子树,右子节点称为右子树。

二叉树的示意图如下:```A/ \B C/ \D E```在二叉树中,每个节点可以有零个、一个或两个子节点。

如果一个节点没有子节点,我们称之为叶子节点。

在上面的示例中,节点 D 和 E 是叶子节点。

二叉树的基本操作包括插入节点、删除节点、查找节点和遍历节点。

插入节点操作可以将一个新节点插入到二叉树中的合适位置。

删除节点操作可以将一个指定的节点从二叉树中删除。

查找节点操作可以在二叉树中查找指定的节点。

遍历节点操作可以按照一定的顺序遍历二叉树中的所有节点。

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

下面将介绍一些常见的应用场景。

1. 二叉搜索树二叉搜索树是一种特殊的二叉树,它的每个节点的值都大于其左子树中的节点的值,小于其右子树中的节点的值。

二叉搜索树可以用来实现快速的查找、插入和删除操作。

它在数据库索引、字典等场景中有着重要的应用。

2. 堆堆是一种特殊的二叉树,它的每个节点的值都大于或小于其子节点的值。

堆可以用来实现优先队列,它在任务调度、操作系统中的内存管理等场景中有着重要的应用。

3. 表达式树表达式树是一种用来表示数学表达式的二叉树。

在表达式树中,每个节点可以是操作符或操作数。

表达式树可以用来实现数学表达式的计算,它在编译器、计算器等场景中有着重要的应用。

4. 平衡二叉树平衡二叉树是一种特殊的二叉树,它的左子树和右子树的高度差不超过1。

平衡二叉树可以用来实现高效的查找、插入和删除操作。

它在数据库索引、自平衡搜索树等场景中有着重要的应用。

三、总结二叉树是一种常用的数据结构,它在计算机科学中有着广泛的应用。

本文介绍了二叉树的定义、基本操作以及一些常见的应用场景。

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

广西工学院计算机学院《数据结构》课程实验报告书实验六二叉树的基本操作及其应用学生姓名:学号:班级:指导老师:专业:计算机学院软件学院提交日期:2013年6月22日1.实验目的1)了解二叉树的特点、掌握二叉树的主要存储结构。

2)掌握二叉树的基本操作,能针对二叉树的具体应用选择相应的存储结构。

3)掌握递归算法的设计方法。

2.实验内容(1)二叉链表表示二叉树,建立一棵二叉树,实现下列基本操作,通过数据测试每个操作的正确性,包括:1. CreateBinTree(&T):建立一颗二叉树:。

2. BinTreeEmpty(T): 判断一棵二叉树是否为空树。

3. PreOrderTraverse(T): 先序遍历二叉树T,并输出节点序列。

4. InOrderTraverse(T): 中序遍历二叉树T,并输出节点序列。

5. PostOrderTraverse(T):后序遍历二叉树T,并输出节点序列。

6. LevelOrderTraverse(T):层次遍历二叉树T,并输出节点序列。

7. Value(T,e):查找值为e的节点,并返回该节点的地址。

8. BinTreeDepth(T):返回二叉树的深度。

9. Parent(T,e):查找二叉树T中值为e的节点的双亲,若e为根节点,操作失败。

(流程图)10. LeftChild(T,e):查找二叉树T中值为e的节点的左孩子,若e没有左孩子,则操作失败。

(流程图)11.RightChild(T,e):查找二叉树T中值为e的节点的右孩子,若e没有右孩子,则操作失败。

12. CountNode(T):计算二叉树中节点的个数。

13. Leaf(T): 计算二叉树中叶子节点的个数。

14. OneChild(T): 计算二叉树中度为1的节点个数。

3.实验要求(1)上机前交实验源程序(纸质版),由学习委员统一收好交老师(附上不交同学名单)。

(2)用一切你能想到的办法解决遇到的问题,培养解决问题的能力。

(3)实验课上进行答辩。

(4)实验报告当场交。

报告内容包括:实验目的、实验内容、实验代码、实验运行结果以及实验体会供五部分。

3.主要算法3.1 顺序存储结构(1)结构定义:#include<stdio.h>#include<stdlib.h>#include <conio.h>#include<malloc.h>//各头文件#define OK 1#define ERROR 0#define OVERFLOW -2typedef char TElemType;//定义宏参//二叉树链表的类型定义typedef struct BiTNode{TElemType data;//二叉树元素元素类型定义struct BiTNode *lchild,*rchild;//定义左右孩子指针}BiTNode,*BinTree;typedef BinTree ElemType;//队列元素类型定义//定义链式队列类型typedef struct QNode{ElemType data;//元素类型定义struct QNode *next;//指向下个结点}QNode,*QueuePtr;////队列指针定义typedef struct{QueuePtr front;//队列头指针QueuePtr rear;//队列尾指针}QUEUE;//先序建立二叉树void CreateBinTree(BinTree &T){//初始条件:二叉树不存在//操作结果:建立一棵二叉树,二叉链表的数据域类型待定TElemType ch;scanf("%c",&ch);if(ch==' ')T=NULL;else{T=(BinTree)malloc(sizeof(BiTNode));//建立头结点if(!T)exit(0);T->data=ch;CreateBinTree(T->lchild);CreateBinTree(T->rchild);}return;}//清空二叉树void ClearBinTree(BinTree &T){//初始条件:二叉树已存在//操作结果:将链表都赋值为空if(T){T->data=' ';//赋域空值ClearBinTree(T->lchild);ClearBinTree(T->rchild);}return;}//判断空二叉树int BinTreeEmpty(BinTree T){//初始条件:二叉树已存在//操作结果:若空返回值1,反之返回0if(!T)return 1;elsereturn 0;}//先序遍历二叉树void PreorderTraverse(BinTree T) {//初始条件:二叉树已存在//操作结果:先序递归遍历Tif(T){printf("%c",T->data);PreorderTraverse(T->lchild);PreorderTraverse(T->rchild);}return;}//中序遍历二叉树void InorderTraverse(BinTree T) {//初始条件:二叉树已存在//操作结果:中序递归遍历Tif(T){InorderTraverse(T->lchild);printf("%c",T->data);InorderTraverse(T->rchild);}return;}//后序遍历二叉树void PostorderTraverse(BinTree T) {//初始条件:二叉树已存在//操作结果:后序递归遍历Tif(T){PostorderTraverse(T->lchild);PostorderTraverse(T->rchild);printf("%c",T->data);}return;}//初始化链式队列void InitQueue(QUEUE *q){//初始条件:队列不存在//操作结果:建立一个队列q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));//建立头尾结点if(!(q->front))//头结点指向NULLexit(0);q->front->next=NULL;}//销掉链式队列void DestroyQueue(QUEUE *q){//初始条件:队列已存在//操作结果:销掉链式队列while(q->front)//头结点还没指向NULL{q->rear=q->front->next;free(q->front);q->front=q->rear;}}//判断空队列int QueueEmpTy(QUEUE q){//初始条件:队列已存在//操作结果:若为空队列返回1,否则返回0if(q.front==q.rear)//头指针等于尾指针return 1;elsereturn 0;}//入队列void EnQueue(QUEUE *q ,ElemType e){//初始条件:队列已存在//操作结果:元素e从队尾入队QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));//建立新结点p if(!p)exit(0);p->data=e;p->next=NULL;q->rear->next=p;q->rear=p;}//出队列void DeQueue(QUEUE *q,ElemType *e){//初始条件:队列已存在//操作结果:元素e从队头输出QueuePtr p;if(q->rear!=q->front)//头指针不等于尾指针{p=q->front->next;*e=p->data;q->front->next=p->next;if(q->rear==p)q->rear=q->front;free(p);}}//层次遍历二叉树void LevelTraverse(BinTree T){ //初始条件:二叉树已存在//操作结果:层次递归遍历TQUEUE q;BinTree a;if(T){InitQueue(&q);//初始化链式队列EnQueue(&q,T);//入队列while(!QueueEmpTy(q)){DeQueue(&q,&a);//出队列printf("%c",a->data);if(a->lchild)//有左孩子EnQueue(&q,a->lchild );if(a->rchild )//有右孩子EnQueue(&q,a->rchild );}}return;}//查找值为e的节点BinTree value(BinTree T, TElemType e){//初始条件:二叉树已存在//操作结果:返回二叉树T中指向元素值为e的结点的指针QUEUE q;BinTree a;if(T){InitQueue(&q);//初始化链式队列EnQueue(&q,T);//入队列while(!QueueEmpTy(q)){DeQueue(&q,&a);//出队列if(a->data ==e)return a;if(a->lchild)//有左孩子EnQueue(&q,a->lchild );if(a->rchild )//有右孩子EnQueue(&q,a->rchild );}}return NULL;}//计算二叉树的深度int BinTreeDepth(BinTree T){//初始条件:二叉树已存在//操作结果:输出二叉树的深度int i,j;if(!T)return 0;i= BinTreeDepth(T->lchild);j=BinTreeDepth(T->rchild);return i>=j?i+1:j+1;}//查找值为e的节点的双亲BinTree Parent(BinTree T,TElemType e){//初始条件:二叉树已存在//操作结果:返回二叉树T中指向元素值为e的结点的双亲的指针QUEUE q;BinTree a;if(T){InitQueue(&q);//初始化链式队列EnQueue(&q,T);//入队列while(!QueueEmpTy(q)){DeQueue(&q,&a);//出队列if(a->lchild&&a->lchild->data==e||a->rchild&&a->rchild->data==e) return a;else{if(a->lchild)//有左孩子EnQueue(&q,a->lchild );if(a->rchild )//有右孩子EnQueue(&q,a->rchild );}}}return NULL;}//查找值为e的节点的左孩子BinTree Leftchild(BinTree T,TElemType e){//初始条件:二叉树已存在//操作结果:返回二叉树T中指向元素值为e的结点的左孩子的指针BinTree p;p=value(T,e);if(p)if(p->lchild)return p->lchild;elsereturn NULL;return NULL;}//查找值为e的节点的右孩子BinTree Rightchild(BinTree T,TElemType e){//初始条件:二叉树已存在//操作结果:返回二叉树T中指向元素值为e的结点的右孩子的指针BinTree p;p=value(T,e);if(p)if(p->rchild)return p->rchild;elsereturn NULL;return NULL;}//计算二叉树中节点的个数int CountNode(BinTree T){//初始条件:二叉树已存在//操作结果:输出二叉树中节点的个数static int sum=0;if(NULL!=T){++sum;CountNode(T->lchild);CountNode(T->rchild);}return sum;}//计算二叉树中叶子节点的个数int Leaf(BinTree T){//初始条件:二叉树已存在//操作结果:输出二叉树中叶子节点的个数if(!T)return 0;if(!T->lchild&&!T->rchild)return 1;return Leaf(T->lchild)+Leaf(T->rchild);}//计算二叉树中度为1的节点个数int Onechild(BinTree T){//初始条件:二叉树已存在//操作结果:输出二叉树中度为1的节点个数if(!T)return 0;if(T->lchild&&!T->rchild||!T->lchild &&T->rchild)return 1+ Onechild(T->lchild)+ Onechild(T->rchild);return Onechild(T->lchild)+ Onechild(T->rchild);}//主函数{BinTree t,p;char e;int j,k;while(1){system("cls");//清屏printf("\n\t***************************************************");printf("\n\t* 二叉树的基本操作及其应用*");printf("\n\t***************************************************\n");printf("\t * 1.建立二叉树 2.先序遍历*\n");printf("\t * 3.中序遍历 4.后序遍历* \n");printf("\t * 5.层次遍历 6.二叉树层数* \n");printf("\t * 7.结点个数8.叶子结点数* \n");printf("\t * 9.单孩子结点数10.查找结点左孩子*\n");printf("\t * 11.查找结点右孩子12.查找结点双亲*\n");printf("\t * 13.清空二叉树0.退出*\n");printf("\t****************************************************\n");printf("请选择选项<0-13>: ");scanf(" %d",&k);if(k<0||k>13){printf("输入有误,请重新输入!");printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();continue;}switch(k)case 1:system("cls");//清屏printf("按先序遍历建立一棵二叉树,输入相应的数据序号:\n");printf("比如: AAA___A___\n");printf("===================================================\n");printf(" ( 1 )");printf("\n");printf(" / \\");printf("\n");printf(" ( 2 ) ( 4 )");printf("\n");printf(" / \\ / \\");printf("\n");printf(" ( 3 ) ( ) ( ) ( )");printf("\n");printf("====================================================\n");printf("\n");printf("你的输入为:");CreateBinTree(t);printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 2:printf("先序遍历二叉树的序列为:");PreorderTraverse(t);//调用先序遍历函数printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 3:printf("中序遍历二叉树的序列为:");InorderTraverse(t);//调用中序遍历函数printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 4:printf("后序遍历二叉树的序列为:");PostorderTraverse(t);//调用后序遍历函数printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 5:printf("层次遍历二叉树的序列为:");LevelTraverse(t);//调用层次遍历函数printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 6:printf("二叉树共有%d层!\n",BinTreeDepth(t));printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;printf("二叉树的结点数为:%d\n",CountNode(t));printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 8:printf("二叉树的叶子结点数为:%d\n",Leaf(t));printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 9:printf("二叉树的单孩子结点数为:%d\n",Onechild(t));printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 10:printf("请输入要查找结点的值:");e=getchar();scanf("%c",&e);p=Parent(t,e);if(p)printf("\n值为%c的结点的双亲结点的值为:%c",e,p->data);elseprintf("\n这结点无双亲!");printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;printf("请输入要查找结点的值:");e=getchar();scanf("%c",&e);p=Leftchild(t,e);if(p)printf("\n值为%c的结点的左孩子结点的值为:%c",e,p->data);elseprintf("\n这结点无左孩子!");printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 12:printf("请输入要查找结点的值:");e=getchar();scanf("%c",&e);p= Rightchild(t,e);if(p)printf("\n值为%c的结点的右孩子结点的值为:%c",e,p->data);elseprintf("\n这结点无右孩子!");printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 13:printf("你真确定要清空二叉树! 1.YES 2.NO\n");printf("请选择项<1-2>: ");scanf("%d",&j);if(j==1)ClearBinTree(t);printf("二叉树清空成功呦!\n");if(j==2)printf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;case 0:printf("你真确定要退出! 1.YES 2.NO\n");printf("请选择项<1-2>: ");scanf("%d",&j);if(j==1)exit(OVERFLOW);elseprintf("\n");printf("\n\t\t\t按任意键进行重新操作!");getch();break;}}}3.流程图1.查找二叉树T中值为e的节点的双亲流程图2.查找二叉树T中值为e的节点的左孩子流程图4.程序运行结果(1)实验内容(1)运行结果如下:2)运行结果如下:运行结果如下:运行结果如下:运行结果如下:运行结果如下:5.心得体会。

相关文档
最新文档