DS之二叉树

二叉树是另一种树型结构,它的特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。

二叉树可以分为5种基本形态:

(1)空二叉树。

(2)仅有根结点的二叉树。

(3)左子树为空的二叉树。

(4)右子树为空空的二叉树。

(5)左,右子树均为非空的二叉树。

图示为:

再延伸一下的话就是画出有三个结点的二叉树的基本形态:

满二叉树

一棵深度为k且有(2^K)-1个结点的二叉树称为满二叉树。

完全二叉树

深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称之为完全二叉树。

这两种特殊形态的二叉树的图示:

对于满二叉树(a)的深度为4,每一层上的结点数都是最大结点数。对这棵满二叉树进行连续编号,约定编号从根结点起,自上而下,自左至右。

对于完全二叉树(b)的深度为4,叶子结点只可能在层次最大的两层上出现,对任一结点,若其右分支下的子孙的最大层为l,则其左分支的子孙的最大层必为l或l+1。

二叉树性质:

(1)在二叉树的第i层上至多有2^(i-1)(i>=1)个结点。

(2)深度为k的二叉树至多有(2^k)-1(k>=1)个结点。

(3)对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。

(4)具有n个结点的完全二叉树的深度为[log2n]+1,其中[log2n]表示取log2n的整数部分。

(5)如果对一棵有n个结点的完全二叉树(其深度为[log2n]+1)的结点按层序编号(从第1层到第[log2n]+1层,每层从左到右),则对任一结点i(1<=i<=n),有:

1如果i=1,则结点i是完全二叉树的根,无双亲;如果i>1,则其双亲PARENT(i)是结点[i/2]。

2如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子LCHILD(i)是结点2i。

3如果2i+1>n,则结点i无右孩子;否则其右孩子RCHILD(i)是结点2i+1。

二叉树的存储结构

顺序存储结构

按照顺序存储结构的定义,在此约定,用一组地址连续的存储单元一次自上而下,自左至右存储完全二叉树的结点元素,即将完全二叉树编号为i的结点元素存储在如上定义的一维数组中下标为i-1的分量中。

顺序存储结构表示:

<span style="font-size:18px;">#define MAX_TREE_SIZE 100
typedef char TElemtype;
TElemtype SqBiTree[MAX_TREE_SIZE];</span>

对于上面的满二叉树和完全二叉树的顺序存储结构为:

对于一般的二叉树的顺序存储结构表示需要用到“空”的结点。

对于上面的一般二叉树的顺序存储数字0或字符^代表的是空结点。在最坏的情况下,一个深度为k且只有k个结点的单支树(树中不存在度为2的结点)需要长度为(2^k)-1的一维数组。

链式存储结构

由二叉树的定义可知,二叉树的结点是由一个数据元素和分别指向其左,右子树的两个分支构成,因此表示二叉树的链式存储中的结点至少包含3个域:数据域,左,右指针域。最常用的就是二叉树的二叉链表存储结构。

二叉链表的结点结构

二叉链表

为了方便访问某结点的双亲,还可以给链表结点增加一个双亲字段parent,用来指向其双亲结点。每个结点由四个域组成,其结点结构为:

这种存储结构既便于查找孩子结点,又便于查找双亲结点;但是,相对于二叉链表存储结构而言,它增加了空间开销。利用这样的结点结构表示的二叉树的链式存储结构被称为三叉链表。

还是来看最常用的二叉树的二叉链表存储表示:

<span style="font-size:18px;">typedef struct BiTNode//重新定义二叉树的二叉链表的结构
{
   TElemType   data;
   struct  BiTNode   *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;</span>

二叉链表的基本操作:

<span style="font-size:18px;">Status createBiTree(BiTree &T)
按先序次序输入二叉树额结点的值(一个字符),#字符表示空字符
构造二叉链表表示的二叉树T
Status PreOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
采用二叉链表存储结构,Visit是对结点操作的应用函数
先序遍历二叉树T,对每个结点调用Visit一次且仅一次
一旦Visit()操作失败,则操作失败
Status InOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
采用二叉链表存储结构,Visit是对结点操作的应用函数
中序遍历二叉树T,对每个结点调用Visit一次且仅一次
一旦Visit()操作失败,则操作失败
Status PostOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
采用二叉链表存储结构,Visit是对结点操作的应用函数
后序遍历二叉树T,对每个结点调用Visit一次且仅一次
一旦Visit()操作失败,则操作失败
Status LeveleOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
采用二叉链表存储结构,Visit是对结点操作的应用函数
层序遍历二叉树T,对每个结点调用Visit一次且仅一次
一旦Visit()操作失败,则操作失败</span>
时间: 2025-01-13 06:18:01

DS之二叉树的相关文章

DS树--二叉树高度

题目描述 给出一棵二叉树,求它的高度.二叉树的创建采用前面实验的方法. 注意,二叉树的层数是从1开始 输入 第一行输入一个整数t,表示有t个二叉树 第二行起输入每个二叉树的先序遍历结果,空树用字符‘0’表示,连续输入t行 输出 每行输出一个二叉树的高度 样例输入 1 AB0C00D00 样例输出 3 提示 #include<iostream> #include<string> using namespace std; class BiTreeNode { public: char

DS树--二叉树之最大路径

题目描述 给定一颗二叉树的逻辑结构(先序遍历的结果,空树用字符‘0’表示,例如AB0C00D00),建立该二叉树的二叉链式存储结构 二叉树的每个结点都有一个权值,从根结点到每个叶子结点将形成一条路径,每条路径的权值等于路径上所有结点的权值和.编程求出二叉树的最大路径权值.如下图所示,共有4个叶子即有4条路径, 路径1权值=5 + 4 + 11 + 7 = 27          路径2权值=5 + 4 + 11 + 2 = 22 路径3权值=5 + 8 + 13 = 26            

DS之遍历二叉树

在二叉树的一些应用中,常常要求在树中查找具有某种特征的结点,或者对树中全部结点逐一进行某种处理.这就提出了一个遍历二叉树的问题,即如何按某条搜索路径巡访树中的每个结点,使得每个结点均被访问一次,而且仅被访问一次. 由二叉树的递归定义可知,二叉树是由三个基本单元构成的:根结点,左子树和右子树.若能依次遍历这三部分,便是遍历了整个二叉树.若限定先左后右的顺序,则遍历二叉树通常有三种算法:先序,中序,后序. 先序遍历二叉树的操作定义为: 若二叉树为空,则空操作:否则; (1)访问根结点:(2)先序遍历

DS二叉树——二叉树之数组存储

二叉树可以采用数组的方法进行存储,把数组中的数据依次自上而下,自左至右存储到二叉树结点中,一般二叉树与完全二叉树对比,比完全二叉树缺少的结点就在数组中用0来表示.,如下图所示 从上图可以看出,右边的是一颗普通的二叉树,当它与左边的完全二叉树对比,发现它比完全二叉树少了第5号结点,所以在数组中用0表示,同样它还少了完全二叉树中的第10.11号结点,所以在数组中也用0表示.结点存储的数据均为非负整数 输入 第一行输入一个整数t,表示有t个二叉树 第二行起,每行输入一个数组,先输入数组长度,再输入数组

DS二叉树--二叉树之父子结点

题目描述 给定一颗二叉树的逻辑结构如下图,(先序遍历的结果,空树用字符'0'表示,例如AB0C00D00),建立该二叉树的二叉链式存储结构. 编写程序输出该树的所有叶子结点和它们的父亲结点 输入 第一行输入一个整数t,表示有t个二叉树 第二行起,按照题目表示的输入方法,输入每个二叉树的先序遍历,连续输入t行 输出 第一行按先序遍历,输出第1个示例的叶子节点 第二行输出第1个示例中与叶子相对应的父亲节点 以此类推输出其它示例的结果 样例输入 3 AB0C00D00 AB00C00 ABCD0000

DS树+图综合练习--二叉树之最大路径

题目描述 给定一颗二叉树的逻辑结构(先序遍历的结果,空树用字符'0'表示,例如AB0C00D00),建立该二叉树的二叉链式存储结构 二叉树的每个结点都有一个权值,从根结点到每个叶子结点将形成一条路径,每条路径的权值等于路径上所有结点的权值和.编程求出二叉树的最大路径权值.如下图所示,共有4个叶子即有4条路径, 路径1权值=5 + 4 + 11 + 7 = 27          路径2权值=5 + 4 + 11 + 2 = 22 路径3权值=5 + 8 + 13 = 26            

DS二叉树—二叉树结点的最大距离

题目描述 二叉树两个结点的距离是一个结点经过双亲结点,祖先结点等中间结点到达另一个结点经过的分支数.二叉树结点的最大距离是所有结点间距离的最大值.例如,下图所示二叉树结点最大距离是3,C和D的距离. 二叉树用先序遍历顺序创建,#表示空树.计算二叉树结点最大距离和最大距离的两个结点(假设二叉树中取最大距离的两个结点唯一). 输入 测试次数T 第2行之后的T行,每行为一棵二叉树先序遍历结果(#表示空树) 输出 对每棵二叉树,输出树的结点最大距离和最大距离的结点,输出格式见样例. 样例输入 3 A##

DS二叉树—二叉树构建与遍历(不含框架)

题目描述 给定一颗二叉树的逻辑结构如下图,(先序遍历的结果,空树用字符‘#’表示,例如AB#C##D##),建立该二叉树的二叉链式存储结构,并输出该二叉树的先序遍历.中序遍历和后序遍历结果. 输入 第一行输入一个整数t,表示有t个二叉树 第二行起输入每个二叉树的先序遍历结果,空树用字符‘#’表示,连续输入t行. 输出 输出每个二叉树的先序遍历.中序遍历和后序遍历结果. 样例输入 2 AB#C##D## AB##C## 样例输出 ABCD BCAD CBDA ABC BAC BCA 提示 #inc

DS二叉树--后序遍历非递归算法

题目描述 求一颗树的后序遍历的非递归算法 要求:必须是非递归算法,使用堆栈对象来实现 建树方法采用“先序遍历+空树用0表示”的方法 算法流程: 输入 第一行输入一个整数t,表示有t个测试数据 第二行起输入二叉树先序遍历的结果,空树用字符‘0’表示,输入t行 输出 逐行输出每个二叉树的后序遍历结果 样例输入 3 AB0C00D00 ABC00D00EF000 ABCD0000E0F00 样例输出 CBDA CDBFEA DCBFEA 提示 #include<iostream> #include&