课程设计二叉树概论

合集下载

数据结构二叉树学习教案

数据结构二叉树学习教案

[1]
A
[2]
B
[3]
C
[4]
D
[5]
E
般不用
[6] [7] [8] [9]
F G H I
A
一 、顺序 存储结 构 按 二 叉 树 的 结点“ 自上而 下、从 左至右 ”编号 ,用一 组连续 (liánxù)的 存储 单元存 储。
B
C
D EF G
H
I
问:顺序存储后能否复原成唯一对应(duìyìng)的二叉树形状? 答:若是完全/满二叉树则可以做到唯一复原。
right_child
data
left_child
right_child
第6页/共17页
第七页,共16页。
二 叉 树 结 点 (jié diǎn)数 据 类 型 定 义 : typedef stru ct B iTNod e {
TElemT ype d ata; struct BiTN ode *lef t_chi ld, *righ t_ch ild; } BiTNo de, * BiTr ee;
f
d
b
e
ac
g i
h
j
第14页/共17页
第十五页,共16页。
习题2:若一棵二叉树,左右子树均有三个结点,其左子树的前 (先)序序列与中序序列相同,右子树的中序序列与后序 序列相同,试构造该树。
习题3:一棵非空的二叉树其先序序列和后序序列正好相反,画出 这棵二叉树的形状。
习题4:已知一棵完全二叉树共有892个结点,试求:⑴ 树的高度; ⑵ 叶结点数;⑶ 单支(度为1)结点数;⑷ 最后(zuìhòu)一 个非终端结点的序号。
第9页/共17页
第十页,共16页。

二叉树概述

二叉树概述
可简写为k=lb(n+1)-1。例如,2.0=2,2.1=3。 若结点个数n=0,则有深度k=-1,满足k=lb(0+1)-1=-1; 若结点个数n=1,则有深度k=0,满足k=lb(1+1)-1=0; 若结点个数n=2,则有深度k=1,满足k=lb(2+1)-1
=0.xx =1; 若结点个数n=3,则有深度k=1,满足k=lb(3+1)-1=1。
二叉树概述
1.二叉树的定义
一、二叉树:是n(n≥0)个结点的有限集合。n=0的树称为空二叉树;n>0的二叉树由 一个根结点以及两棵互不相交的、分别称为左子树和右子树的二叉树组成 。
逻辑结构: 一对二(1:2) 基本特征: ① 每个结点最多只有两棵子树(不存在度大于2的结点); ② 左子树和右子树次序不能颠倒。所以下面是两棵不同的树 注意:二叉树不是有序树
3.二叉树的性质
性质1 在一棵非空二叉树的第i层上至多有2i个结点(i≥0)。
性质2 深度为k的二叉树至多有2k+1-1个结点。 说明:深度k=-1,表示没有一个结点;深度k=0,表示只有一个根结点。
性质3 对于一棵非空的二叉树,如果叶结点个数为n0,度为2的结点数为n2, 则有 n0= n2+1。 证明:设n为二叉树的结点总数,n1为二叉树中度为1的结点个数,则有: n = n0 + n1 + n2
A
B
C
D
E
F
G
H I J K L MN O
A
B
C
D
E
F
G
H IJ
(a)满二叉树
(b)完全二叉树
问题:一个高度为h的完全二叉树最多有多少个结点?最少有多少个结点?

《二叉树的概念》课件

《二叉树的概念》课件
过程中进行一些特定的操作。
05
二叉树的应用
Chapter
在数据结构中的应用
二叉搜索树
二叉搜索树是一种特殊的二叉树,它的每个节点的左子树上的所有元素都小于 该节点,右子树上的所有元素都大于该节点。这种数据结构可以用于快速查找 、插入和删除操作。
AVL树和红黑树
这两种二叉树都是自平衡二叉搜索树,它们通过调整节点的左右子树的高度来 保持树的平衡,从而在插入、删除等操作时具有较好的性能。
VS
详细描述
平衡二叉树的特点是,它的左右子树的高 度差不会超过1,且左右子树都是平衡二 叉树。平衡二叉树的性质还包括,它的所 有叶节点的层数相等,且所有非叶节点的 左右子树的高度差不超过1。平衡二叉树 的查找、插入和删除操作的时间复杂度为 O(log n),其中n为节点数。
04
二叉树的遍历
Chapter
决策树
在机器学习和人工智能领域,决策树 是一种重要的分类和回归方法。其基 础结构就是二叉树,通过构建决策树 ,可以解决分类和回归问题。
THANKS
感谢观看
代码表示法
总结词:严谨规范
详细描述:使用编程语言的语法结构来表示二叉树,每个节点用对象或结构体表示,节点间的关系通 过指针或引用表示,严谨规范,易于编写和调试。
03
二叉树的性质
Chapter
深度最大的二叉树
总结词
深度最大的二叉树是指具有最大 可能深度的二叉树。
详细描述
在二叉树中,深度最大的二叉树 是满二叉树,即每个层级都完全 填满,没有空缺的节点。满二叉 树的深度等于其节点总数减一。
02
二叉树的表示方法
Chapter
图形表示法
总结词:直观明了
详细描述:通过图形的方式展示二叉树的结构,每个节点用圆圈或方框表示,节 点间的关系用线段表示,直观易懂,易于理解。

树和二叉树——精选推荐

树和二叉树——精选推荐

第6章 树和二叉树内容概要:本章主要介绍树,二叉树,最优二叉树的相关概念和操作,存储结构和相应的操作,并在综合应用设计中,给出了对应算法的C 语言实现。

教学目标1.理解各种树和森林与二叉树的相应操作。

2.熟练掌握二叉树的各种遍历算法,并能灵活运用遍历算法实现二叉树的其他操作。

3.熟练掌握二叉树和树的各种存储结构及其建立的算法。

4.掌握哈夫曼编码的方法。

5.通过综合应用设计,掌握各种算法的C 语言实现过程。

基本知识点:树和二叉树的定义、二叉树的存储表示、二叉树的遍历以及其它操作的实现、树和森林的存储表示、树和森林的遍历以及其它操作的实现、最优树和赫夫曼编码重点:二叉树的性质、二叉树的遍历及其应用,构造哈夫曼树。

难点:编写实现二叉树和树的各种操作的递归算法。

本章知识体系结构:课时安排:6个课时树的定义 树树的性质 树的逻辑表示法 树形表示法 树的存储结构 双亲存储结构 文氏表示法凹入表示法 括号表示法 孩子存储结构 孩子双亲存储结构二叉树二叉树的定义 二叉树的性质二叉树的逻辑表示法(采用树的逻辑表示法)二叉树的存储结构二叉树的顺序存储结构先序遍历 中序遍历 后序遍历二叉树的遍历 二叉树的链式存储结构(二叉链) 由先序序列和中序序列构造二叉树 由中序序列和后序序列构造二叉树二叉树的构造 二叉树的线索化 哈夫曼树二叉树和树之间的差别 二叉树与树、森林之间的转换二叉树和树课程数据结构教学教具多媒体课件学时2班级06网络教学日期/课时 /2课时教学单元第6章树和二叉树教学方法讲授(PPT)教学目标掌握树、二叉树的基本概念和术语,二叉树的性质教学重点二叉树的定义、二叉树的性质、链式存储结构教学难点二叉树的性质、链式存储二叉树的基本操作组织教学一、树的定义二、树的基本概念三、二叉树的定义、性质四、二叉树的顺序存储结构和链式存储结构五、小结作业复习本讲内容并预习下一讲内容课堂情况及课后分析课程数据结构教学教具多媒体课件学时2班级06网络教学日期/课时 /2课时教学单元第6章树和二叉树教学方法讲授(PPT)教学目标掌握二叉树遍历的三种方法及二叉树的基本操作教学重点二叉树的遍历算法教学难点中序与后序遍历的非递归算法组织教学一、复习二叉树的定义二、遍历二叉树的三种方法三、递归法遍历二叉树四、二叉树的基本操作五、总结作业复习本讲内容并预习下一讲内容课堂情况及课后分析课程数据结构教学教具多媒体课件学时2班级06网络教学日期/课时 /2课时教学单元第6章树和二叉树教学方法讲授(PPT)教学目标理解树与森林的转换,掌握哈夫曼树教学重点哈夫曼树教学难点树与森林的转换组织教学一、导入二、树与森林三、哈夫曼树四、小结作业习题6课堂情况及课后分析前面几章讨论的数据结构都属于线性结构,线性结构的特点是逻辑结构简单,易于进行查找、插入和删除等操作,可用于描述客观世界中具有单一前驱和后继的数据关系。

二叉树教案

二叉树教案

二叉树教案一、教学目标:1.了解二叉树的定义和性质。

2.学会二叉树的遍历算法(前序遍历、中序遍历、后序遍历)。

3.掌握二叉树的基本操作(创建二叉树、插入节点、删除节点)。

二、教学重点和难点:1.二叉树的定义和性质。

2.二叉树的遍历算法。

3.二叉树的基本操作。

三、教学准备:1.教师准备:PPT、计算机、投影仪。

2.学生准备:课前预习、纸笔。

四、教学过程:Step 1 导入新课教师通过提问的方式,引导学生回顾树的基本概念,并激发学生对二叉树的兴趣。

Step 2 二叉树的定义和性质教师给出二叉树的定义,并带领学生讨论二叉树的性质(每个节点最多有两个子节点,左子树和右子树)。

Step 3 二叉树的遍历算法1.前序遍历:先访问根节点,然后递归遍历左子树,再递归遍历右子树。

2.中序遍历:先递归遍历左子树,然后访问根节点,再递归遍历右子树。

3.后序遍历:先递归遍历左子树,然后递归遍历右子树,最后访问根节点。

Step 4 二叉树的基本操作1.创建二叉树:教师通过示例向学生展示二叉树的创建过程。

2.插入节点:教师通过示例向学生展示如何插入节点,并解释插入节点的规则。

3.删除节点:教师通过示例向学生展示如何删除节点,并解释删除节点的规则。

Step 5 练习与拓展1.教师设计练习题,让学生运用所学知识进行练习。

2.鼓励学生拓展二叉树的其他应用领域,并进行讨论。

五、教学反思本节课通过讲解二叉树的定义和性质,以及二叉树的遍历算法和基本操作,使学生对二叉树有了基本的了解和掌握。

通过练习和拓展,巩固了学生的学习成果,并培养了学生的分析和解决问题的能力。

但是,由于时间有限,学生的实际操作机会较少,可以在课后布置相关的作业,加深学生的理解和应用能力。

数据结构课程设计二 叉 树 遍 历 及 应 用

数据结构课程设计二 叉 树 遍 历 及 应 用

实验报告课程:数据结构课程设计设计题目:二叉树遍历及应用学号:班级:软件11k1姓名: 南方小羊指导教师:刘军二叉树的遍历1、问题描述利用先序遍历建立一棵二叉树,并分别用前序、中序、后序遍历该二叉树2、节点形式Lchild data Rchild3、说明(1)输入数据:1,2,3,0,0,4,0,0,5,0,0其中“0”表示空子树。

(2)输出数据:先序:1,2,3,4,5中序:3,2,4,1,5后序:3,4,2,5,1二叉树的应用1、问题描述运用二叉树的遍历的算法,编写算法分别实现如下功能。

(1)求出二叉树中的结点的总数。

(2)求出二叉树中的叶子数目。

(3)求出二叉树的深度。

运用上题所建立的二叉树,求出其结点总数、叶子数目、深度,最后释放所有结点。

二叉树结点结构中包数据域(data),指针域(*lchild,*rchild)。

结点结构的代码如下:typedef struct tree{int data;struct tree *lchild,*rchild;}*bitree;本实例使用的是二叉树,首先建立头结点,并且保存数据,然后根据递归方法,分别建立其左右孩子结点,且左右孩子结点的指针域指向空。

先序递归遍历时,输出第一个根结点数据,然后分别遍历左子树再遍历右子树,中序遍历,先访问根结点的左子树输出数据,再输出根结点的数据,再访问右子树,后序遍历先访问根结点的右子树,再访问根结点,再访问左子树输出。

统计二叉树叶子的个数可以看成一个遍历问题,访问一个结点,判断该结点是否为叶子,如果是将叶子树加1,可以采用任何遍历实现,求二叉树的深度是假设根结点为第一层的结点,所有K层结点的左右孩子在K+1层,所以可以通过先序遍历计算二叉树中每个结点的层数,其中最大的就是二叉树的深度。

四、实验心得:树结构是数据结构课程的典型内容,而且综合使用了多种逻辑结构,具有代表性,可以锻炼个人编程能力。

在刚开始选题后,我感觉无从下手,一是因为没有实践经验,二是因为对数据结构课程的内容没有把握到位,然后在参考一些专业书籍并且学习了之前其他人的课程设计,才逐渐可以上手去自己做。

数据结构_二叉树的遍历_课程设计

数据结构_二叉树的遍历_课程设计

8
if(bt!=NULL)/*二叉树 bt 非空*/ { inorder(bt->lchild);/*中序遍历 bt 的左子树*/ printf("%c",bt->data);/*访问结点 bt*/ inorder(bt->rchild);/*中序遍历 bt 的右子树*/ } } void postorder(bitree *bt)/*后序序遍历二叉树*/ { if(bt!=NULL) { postorder(bt->lchild); postorder(bt->rchild); printf("%c",bt->data); } }
3.2.2 二叉树的中序递归遍历算法
void inorder(bitree *bt)/*中序序遍历二叉树*/ { if(bt!=NULL)/*二叉树 bt 非空*/ { inorder(bt->lchild);/*中序遍历 bt 的左子树*/ printf("%c",bt->data);/*访问结点 bt*/ inorder(bt->rchild);/*中序遍历 bt 的右子树*/ } }
图 1 “菜单”界面
图2
创建二叉树
5
图 3 二叉树的先序遍历
图4
二叉树的中序输出
6
图 5 二叉树的后序输出
五:实验总结 虽然做的过程中出现很多错误。但是最后还是一一纠正了,并在其中发现了自 身的不足,补学补差。最后终于完成了。
六:源程序附录
#include<stdio.h> #include<stdlib.h> typedef char datatype; typedef struct node { datatype data;/*数据元素*/ struct node *lchild,*rchild;/*指向左,右孩子*/ }bitree; bitree *root;/*二叉树结点类型定义*/ bitree *creatbitree(bitree *root)/*创建二叉树*/ { char ch;

数据结构详细教案——树与二叉树

数据结构详细教案——树与二叉树

数据结构详细教案——树与二叉树一、教学目标1.了解树和二叉树的基本概念和特点;2.掌握树和二叉树的基本操作;3.能够通过递归遍历树和二叉树。

二、教学重难点1.树和二叉树的基本概念和特点;2.递归遍历树和二叉树。

三、教学内容1.树的概念和特点1.1树的定义树是n(n>=0)个节点的有限集。

当n=0时,称为空树;如果不为空树,则1. 树有且仅有一个特殊节点被称为根(Root);2.其余节点可分为m(m>0)个互不相交的有限集T1,T2,...,Tm,其中每个集合又是一棵树。

1.2节点间的关系- 父节点(parent)是当前节点的直接上级节点;- 子节点(child)是当前节点的直接下级节点;- 兄弟节点(sibling)是具有同一父节点的节点;- 祖先节点(ancestor)是通过从当前节点到根的任意路径可以到达的节点;- 子孙节点(descendant)是通过从该节点到子树的任意节点可以到达的节点。

1.3树的特点-树是一个有层次的结构,可以看作是一个鱼骨图;-树中的每个节点都可以有多个子节点,但只有一个父节点;-树中的节点之间是唯一的,不存在重复节点;-树中的任意两个节点之间都有且仅有一条路径连接。

2.二叉树的概念和特点2.1二叉树的定义二叉树是一种特殊的树结构,它的每个节点最多只能有两个子节点,分别称为左子节点和右子节点。

2.2二叉树的特点-二叉树的度最大为2,即每个节点最多有两个子节点;-二叉树的第i层最多有2^(i-1)个节点;-对于任意一颗二叉树,如果其叶子节点数为n0,度为2的节点数为n2,则有n0=n2+1;-完全二叉树是一种特殊的二叉树,除了最后一层的叶子节点外,每一层的节点都是满的。

四、教学过程1.讲解树和二叉树的基本概念和特点,引导学生理解树和二叉树的定义和节点间的关系。

2.分析树和二叉树的基本操作,并通过实例演示操作过程,让学生掌握操作的步骤和方法。

3.运用递归算法遍历树和二叉树的过程,详细讲解前序遍历、中序遍历和后序遍历的定义和实现方法。

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

安徽理工大学数据结构课程设计说明书题目: 二叉树的遍历集成院系:计算机科学与工程学院专业班级:学号:学生姓名:指导教师:2015年 01 月 9 日安徽理工大学课程设计(论文)任务书计算机科学与工程学院信息安全教研室2014年 12 月 18 日目录1.需求分析 (1)2、总体设计 (1)2.1 程序目录 (1)2.2 算法流程 (3)3、详细设计 (3)3.1 界面设计 (3)3.2 详细代码设计 (4)3.3 调试分析 (10)4、总结 (14)参考文献 (15)代码详述 (15)1.需求分析“数据结构”是计算机程序设计的重要理论技术基础,它不仅是计算机学科的核心,而且也成为其他理工类学科必修课程,所谓”数据结构”是相互之间存在一种或多种特定关系的数据元素的集合.数据元素之间的相互关系成为结构,结构一般有线性结构,树形结构,图状结构,本程序所做的就是树形结构的二叉树的遍历算法和线索化查找.本程序使用VC6.0++编写,具体实现功能有二叉树的遍历,包括先序遍历,中序遍历,后序遍历的递归算法以及非递归算法.另外本程序还有可线索化二叉树的功能,由此可以得到二叉树某个节点的前驱和后继.题目要求为:1.实现二叉树的各种遍历。

包括先序遍历、中序遍历、后序遍历的递归和非递归算法、以及层次遍历。

2.要求能查找任一结点在某种遍历序列中的前驱和后继。

3.界面友好,易于操作。

可采用菜单或其它人机对话方式进行选择。

由小组一起制作,本人做小组汇总工作,并在基础上加了查找某个节点是否存在二叉树,以及求二叉树总节点数等一些简单功能2、总体设计2.1 程序目录(1)typedef struct node二叉树的定义,包含数据域data,左孩子lchild,右孩子rchild,若二叉树为空,则头结点指向空指针,并且data数据域为字符型数据.(2)BiTree CreatBiTree1(BiTree &T)创建一颗二叉树,需要按照先序遍历输入相应字符才能构造出二叉树,其中用星号”*”来代表空字符.(3)void Preorder1(BiTree T)先序遍历递归算法,调用此函数可以获得输入二叉树的先序序列(4)void Preorder2(BiTree T)先序遍历非递归算法,和上面一样,调用此函数可以获得二叉树先序序列(5)void Inorder1(BiTree T)中序遍历递归算法,调用此函数可以获得输入二叉树的中序序列(6)void Inorder2(BiTree T)中序遍历非递归算法,和上面一样,调用此函数可以获得二叉树中序序列(7)void Postorder1(BiTree T)后序遍历递归算法,调用此函数可以获得输入二叉树的后序序列(8)void Postorder2(BiTree &T)和typedef struct stacknode后序遍历非递归算法,和其中用到的哨兵结构体.调用此函数可以获得二叉树后序序列(9)void Levelorder(BiTree T,int NodeNum)层序遍历二叉树,需要手动输入节点数,然后即可进行二叉树的层序遍历,输出遍历结果(10)void InThreading(BiTree p)线索化二叉树中需要用到的线索化前驱和后继(11)void InOrderThreading(BiTree &Thrt,BiTree T)以中序遍历来线索化二叉树,让空节点分别指向当前节点的前驱后继(12)BiTree Inprenode(BiTree p)和BiTree Inpostnode(BiTree p)线索化后用此函数查找二叉树的前驱和后继(13)BiTree search(BiTree BT,char x)查找某个二叉树节点,其中x为要查找节点的data域的值(14)main( )主函数利用while()和switch()语句构造可视化友好界面 2.2 算法流程小组分工设计独立的函数,比如三种遍历,层序遍历,二叉树线索化等,然后再综合起来,用主函数调用即可33.1 界面设计(1)打开程序后首先是按照先序序列输入二叉树,其中用“*”号表示空节点。

mainCreatBiTree Inorder1Preorder2 Preorder1Inorder2 Levelorder Postorder1 Postorder2InThreading InOrderThre Inprenode search图1 二叉树输入界面(2)输入完二叉树后进入功能选择页面,选择对应的编号,实行相应的操作图2 二叉树功能选择页面3.2 详细代码设计(1)创建一个二叉树,用户按照二叉树先序遍历顺序输入相应data域数据,使用getchar()读入并赋给c,利用T节点,以及左右递归,即可建立出一颗二叉树。

BiTree CreatBiTree1(BiTree &T){char ch;if((ch=getchar())=='*')T=NULL; //读入星号,返回空指针else{T=(BiTNode *)malloc(sizeof(BiTNode));//生成结点if(!T)return 0;T->data=ch;T->LTag=0;T->RTag=0;CreatBiTree1(T->lchild); //构造左子树CreatBiTree1(T->rchild); //构造右子树return(T);}}(2)先序递归算法,读取头节点后,输出,接下来使用递归算法,不断地向下延伸读取,输出即可。

void Preorder1(BiTree T){if(T) {printf("%c",T->data); //访问结点Preorder1(T->lchild); //先序遍历左子树Preorder1(T->rchild); //先序遍历右子树}}(3)先序遍历非递归算法,设置一个stack的栈用来存储读取的二叉树序列,利用栈先进后出的特性,输出栈即为先序遍历.void Preorder2(BiTree T){ B iTree stack[Max],p;int top;if( T!=NULL){top=0;p=T;while(p!=NULL||top>0){while(p!=NULL){printf("%c",p->data);stack[top]=p;top++;p=p->lchild;}if(top>0){ top--;p=stack[top];p=p->rchild;}}}}(4)中序遍历递归算法和先序遍历思想差不多,只是在遍历完左边后再输出头节点.void Inorder1(BiTree T){if(T) {Inorder1(T->lchild); //中序遍历左子树printf("%c",T->data); //访问结点Inorder1(T->rchild); //中序遍历右子树}}(5)中序遍历非递归算法,同理也是利用栈的特性来存储读取出来的data域的值,修改下出栈方式即可.void Inorder2(BiTree T){ BiTree stack[Max],p;int top;if( T!=NULL){top=0;p=T;while(p!=NULL||top>0){while(p!=NULL){stack[top]=p;top++;p=p->lchild;}if(top>0){ top--;p=stack[top];printf("%c",p->data);p=p->rchild;}}}}(6)后序遍历递归算法和先序遍历思想差不多,只是在遍历完最后后再输出头节点.void Postorder1(BiTree T){if(T) {Postorder1(T->lchild); //后序遍历左子树Postorder1(T->rchild); //后序遍历右子树printf("%c",T->data); //访问结点}}(7)后序遍历非递归算法,首先设置一个typedef struct stacknode的结构体为监查哨兵,输出过的节点都做上标记,防止二次输出.typedef struct{BiTree ptr;int tag;}stacknode; //设置哨兵void Postorder2(BiTree &T){ stacknode s[Max],x;BiTree p=T;int top;if(T!=NULL){top=0;p=T;do{while(p!=NULL){s[top].ptr=p;s[top].tag=1;top++;p=p->lchild;}while(top>0&&s[top-1].tag==2){x=s[--top];p=x.ptr;printf("%c",p->data);}if(top>0){s[top-1].tag=2;p=s[top-1].ptr->rchild;}}while(top>0);}}(8)层序遍历二叉树,利用指针数组*cq[Max]进行出队入队操作,再遍历左子树,最后再遍历右子树.void Levelorder(BiTree T,int NodeNum){int front=0,rear=1;BiTNode *cq[Max],*p; //定义结点的指针数组cqcq[1]=T; //根入队while(front!=rear){front=(front+1)%NodeNum;p=cq[front]; //出队printf("%c",p->data); //出队,输出结点的值if(p->lchild!=NULL){rear=(rear+1)%NodeNum;cq[rear]=p->lchild; //左子树入队}if(p->rchild!=NULL){rear=(rear+1)%NodeNum;cq[rear]=p->rchild; //右子树入队} }}(9)线索化二叉树,利用void InThreading(BiTree p)和void InOrderThreading(BiTree &Thrt,BiTree T)可完成二叉树中序线索化.主要思想是使二叉树中的空节点指向其前驱和后继.void InThreading(BiTree p)//线索化二叉树前驱后继{if(p){InThreading(p->lchild);if(!p->lchild){p->LTag=1;p->lchild=pre;}if(!pre->rchild){pre->RTag=1;pre->rchild=p;}pre=p;InThreading(p->rchild);}}void InOrderThreading(BiTree &Thrt,BiTree T){Thrt=(BiTree)malloc(sizeof(BiTNode));Thrt->LTag=0;Thrt->RTag=1;Thrt->rchild=Thrt;if(!T)Thrt->lchild=Thrt;else{Thrt->lchild=T;pre=Thrt;InThreading(T);pre->rchild=Thrt;pre->RTag=1;Thrt->rchild=pre;}}(10)查找二叉树的前驱和后继,基于中序线索化二叉树后,根据LTag和RTag的只能即可确定出节点的前驱和后继.BiTree Inprenode(BiTree p)//查找前驱{BiTree pre;pre=p->lchild;if (p->LTag!=1)while(pre->RTag==0)pre=pre->rchild;return(pre);}BiTree Inpostnode(BiTree p)//查找后继{BiTree post;post=p->rchild;if (p->RTag!=1)while(post->LTag==0)post=post->lchild;return(post);}(11)查找某个二叉树节点.根据data域的值,可以利用递归遍历查找出二叉树的对应节点的data域的值,从而确定所要查询的节点是否在二叉树中.BiTree search(BiTree BT,char x)//查找结点X,BiTree是二叉树结点类型的指针{if(BT->data==x) return BT;else if(BT->lchild)return search(BT->lchild,x);else if(BT->rchild)return search(BT->rchild,x);elsereturn NULL;}3.3 调试分析(1)先序递归遍历图3 二叉树先序递归遍历(2)先序非递归遍历图4 二叉树先序非递归遍历(3)中序递归遍历图5 二叉树中序递归遍历(4)中序非递归遍历图6 二叉树中序非递归遍历(5)后序递归遍历图7 二叉树后序递归遍历(6)后序非递归遍历图8 二叉树后序非递归遍历(7)层序遍历图8 层序遍历二叉树(8)查找二叉树节点的前驱和后继图9 查找前驱和后继(9)判断节点是否在二叉树内图10 判断节点是否在二叉树内4、总结数据结构是一门博大精深的课程,尤其是通过这次课程设计,我深切是了解到算法为何是程序的灵魂了,算法决定一个程序的好与坏,效率高与效率低.在以前的c语言学习中,编写的程序大多数都是简短的实现单一功能的程序,没有了解到程序与程序之间的联系,和不同算法之间是如何相联系的.而这次试验却完全不一样.编写程序前需要自己做一个好的规划和设计,不断去了解所需要的编写的功能概念和算法,一开始总是很难,但随着不断地深入,我渐渐喜欢上了这种不断探索的过程,当然程序是不断出错的,而一次又一次的解决错误的过程,却使我体会到成功的喜悦.最终在自己的努力下,程序可以运行起来,实现自己所需要的功能,这是一件自豪的事情.通过这次试验,我也体会到数据结构的重要性,只有真正理解数据类型的区别和数据类型之间的转换,才能更好地做出程序,比如查找前驱和后继的时候用户输入的是char型的数据,而查找函数需要的是BiTree的结构体数据,因为就需要search函数来转化,找到这个节点,从而查找出前驱和后继,这就是数据利用的一小点,而这一小点,让我在程序设计中避免了好多错误,巧妙地利用数据之间的关系,就可以灵活的调用函数,而避免出错.这次试验中我有一个疑惑的部分,我输入data数据,使用scanf(“%c”,ch),在运行过程中却没法输入,这个令我很疑惑,我将程序改为cin>>ch;就可以了,我认为%c 字符把enter当成字符了,而cin却不把enter当成字符,所以可以输入.像这样的小问题,我不断发现,不断解决,最终提高自己,感受到数据结构的魅力,参考文献[1]严蔚敏,吴伟民.数据结构(C语言版).北京:清华大学出版社,1997.4代码详述#include"stdio.h"#include"string.h"#include"malloc.h"#include <iostream>using namespace std;#define Max 20 //结点的最大个数typedef struct node{char data;struct node *lchild,*rchild;int LTag,RTag,flag;//用于线索化二叉树}BiTNode,*BiTree; //自定义二叉树的结点类型BiTree pre;//用于线索化int NodeNum; //NodeNum为结点数//二叉树线索化之前先输入二叉树BiTree CreatBiTree1(BiTree &T){char ch;if((ch=getchar())=='*')T=NULL; //读入星号,返回空指针else{T=(BiTNode *)malloc(sizeof(BiTNode));//生成结点if(!T)return 0;T->data=ch;T->LTag=0;T->RTag=0;CreatBiTree1(T->lchild); //构造左子树CreatBiTree1(T->rchild); //构造右子树return(T);}}//DLR 先序遍历递归算法void Preorder1(BiTree T){if(T) {printf("%c",T->data); //访问结点Preorder1(T->lchild); //先序遍历左子树Preorder1(T->rchild); //先序遍历右子树}}//DLR 先序遍历非递归算法void Preorder2(BiTree T){ BiTree stack[Max],p;int top;if( T!=NULL){top=0;p=T;while(p!=NULL||top>0){while(p!=NULL){printf("%c",p->data);stack[top]=p;top++;p=p->lchild;}if(top>0){ top--;p=stack[top];p=p->rchild;}}}}//LDR 中序遍历递归算法void Inorder1(BiTree T){if(T) {Inorder1(T->lchild); //中序遍历左子树printf("%c",T->data); //访问结点Inorder1(T->rchild); //中序遍历右子树}}//LDR 中序遍历非递归算法void Inorder2(BiTree T){ BiTree stack[Max],p;int top;if( T!=NULL){top=0;p=T;while(p!=NULL||top>0){while(p!=NULL){stack[top]=p;top++;p=p->lchild;}if(top>0){ top--;p=stack[top];printf("%c",p->data);p=p->rchild;}}}}//LRD 后序遍历递归算法void Postorder1(BiTree T){if(T) {Postorder1(T->lchild); //后序遍历左子树Postorder1(T->rchild); //后序遍历右子树printf("%c",T->data); //访问结点}}//LRD 后序遍历非递归算法typedef struct{BiTree ptr;int tag;}stacknode; //设置哨兵void Postorder2(BiTree &T){ stacknode s[Max],x;BiTree p=T;int top;if(T!=NULL){top=0;p=T;do{while(p!=NULL){s[top].ptr=p;s[top].tag=1;top++;p=p->lchild;}while(top>0&&s[top-1].tag==2){x=s[--top];p=x.ptr;printf("%c",p->data);}if(top>0){s[top-1].tag=2;p=s[top-1].ptr->rchild;}}while(top>0);}}//层次遍历二叉树void Levelorder(BiTree T,int NodeNum){int front=0,rear=1;BiTNode *cq[Max],*p; //定义结点的指针数组cqcq[1]=T; //根入队while(front!=rear){front=(front+1)%NodeNum;p=cq[front]; //出队printf("%c",p->data); //出队,输出结点的值if(p->lchild!=NULL){rear=(rear+1)%NodeNum;cq[rear]=p->lchild; //左子树入队}if(p->rchild!=NULL){rear=(rear+1)%NodeNum;cq[rear]=p->rchild; //右子树入队}}}//中序遍历下节点的前驱后继void InThreading(BiTree p)//线索化二叉树前驱后继{if(p){InThreading(p->lchild);if(!p->lchild){p->LTag=1;p->lchild=pre;}if(!pre->rchild){pre->RTag=1;pre->rchild=p;}pre=p;InThreading(p->rchild);}}void InOrderThreading(BiTree &Thrt,BiTree T){Thrt=(BiTree)malloc(sizeof(BiTNode));Thrt->LTag=0;Thrt->RTag=1;Thrt->rchild=Thrt;if(!T)Thrt->lchild=Thrt;else{Thrt->lchild=T;pre=Thrt;InThreading(T);pre->rchild=Thrt;pre->RTag=1;Thrt->rchild=pre;}}BiTree Inprenode(BiTree p)//查找前驱{BiTree pre;pre=p->lchild;if (p->LTag!=1)while(pre->RTag==0)pre=pre->rchild;return(pre);}BiTree Inpostnode(BiTree p)//查找后继{BiTree post;post=p->rchild;if (p->RTag!=1)while(post->LTag==0)post=post->lchild;return(post);}//查找某个节点BiTree search(BiTree BT,char x)//查找结点X,BiTree是二叉树结点类型的指针{if(BT->data==x) return BT;else if(BT->lchild)return search(BT->lchild,x);else if(BT->rchild)return search(BT->rchild,x);elsereturn 0;}//主函数int main(){BiTree root,t,k1;char c;int i;printf("\n");printf("创建二叉树; 输入完全二叉树的先序序列:"); //输入完全二叉树的先序序列,// 用*代表虚结点,如ABD###CE##F## CreatBiTree1(root); //创建二叉树,返回根结点do { //从菜单中选择遍历方式,输入序号。

相关文档
最新文档