二叉树的递归定义及存储

定义


最多有两棵子树的有序树,称为二叉树。二叉树是一种特殊的

递归定义:二叉树是n(n>=0)个有限结点构成的集合。N=0称为空二叉树;n>0的二叉树由一个根结点和两互不相交的,分别称为左子树和右子树的二叉树构成。

二叉树中任何结点的第1个子树称为其左子树,左子树的根称为该结点的左孩子;二叉树中任何结点的第2个子树称为其右子树,左子树的根称为该结点的右孩子。如下图是一个二叉树:

图1.二叉树

满二叉树和完全二叉树

在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且叶子结点都在同一层上,这样的二叉树称作满二叉树。一棵深度为k且由2k-1个结点的二叉树称为满二叉树。

如果一棵具有n个结点的二叉树的结构与满二叉树的前n个结点的结构相同,这样的二叉树称作完全二叉树

图2. 满二叉树和完全二叉树


基本性质


这里规定二叉树的根结点的层次为1。

性质1:则二叉树的第i 层最多有2i-1个结点(在此二叉树的层次从1开始,i≥1)

性质2:深度为k的二叉树最多有2k-1个结点。(k≥1)

性质3:对任何一棵二叉树T, 如果其叶结点个数为n0, 度为2的非叶结点个数为n2, 则有

             n0 = n2 + 1

性质4:具有 n(n>0)个结点的完全二叉树的深度为⎣log2n⎦+1;⎦x⎦表示不超过x的最大整数。

性质5:如果对一棵有n个结点的完全二叉树的结点按层序编号(从第1层到第⎣l og2n⎦ +1层,每层从左到右),则对任一结点i(1≤i≤n),有:

(1)如果i=1,则结点i无双亲,是二叉树的根;如果i>1,则其双亲是结点⎣i/2⎦。

(2) 如果2i<=n, 则结点i的左孩子结点是2i;否则,结点i为叶子结点,无左孩子结点。

(3)如果2i+1<=n,则结点i的右孩子是结点2i+1; 否则,结点i为叶子结点,无右孩子结点。


抽象数据类型


数据元素:具有相同特性的数据元素的集合。

结构关系:树中数据元素间的结构关系由二叉树的定义确定。

基本操作:树的主要操作有

(1)创建树IntTree(&T)

(2)销毁树DestroyTree(&T)

(3)构造树CreatTree(&T,deinition)

(4)置空树ClearTree(&T)

(5)判空树TreeEmpty(T)

(6)求树的深度TreeDepth(T)

(7)获得树根Root(T)

(8)获取结点Value(T,cur_e,&e),将树中结点cur_e存入e单元中。

(9)数据赋值Assign(T,cur_e,value),将结点value,赋值于树T的结点cur_e中。

(10)获得双亲Parent(T,cur_e),返回树T中结点cur_e的双亲结点。

(11)获得最左孩子LeftChild(T,cur_e),返回树T中结点cur_e的最左孩子。

(12)获得右兄弟RightSibling(T,cur_e),返回树T中结点cur_e的右兄弟。

(13)插入子树InsertChild(&T,&p,i,c),将树c插入到树T中p指向结点的第i个子树之前。

(14)删除子树DeleteChild(&T,&p,i),删除树T中p指向结点的第i个子树。

(15)遍历树TraverseTree(T,visit())


二叉树的存储结构


 二叉树是非线性结构,即每个数据结点至多只有一个前驱,但可以有多个后继。它可采用顺序存储结构和链式存储结构。

1.顺序存储结构

    二叉树的顺序存储,就是用一组连续的存储单元存放二叉树中的结点。因此,必须把二叉树的所有结点安排成为一个恰当的序列,结点在这个序列中的相互位置能反映出结点之间的逻辑关系,用编号的方法从树根起,自上层至下层,每层自左至右地给所有结点编号,缺点是有可能对存储空间造成极大的浪费,在最坏的情况下,一个深度为k且只有k个结点的右单支树需要2k-1个结点存储空间。依据二叉树的性质,完全二叉树和满二叉树采用顺序存储比较合适,树中结点的序号可以唯一地反映出结点之间的逻辑关系,这样既能够最大可能地节省存储空间,又可以利用数组元素的下标值确定结点在二叉树中的位置,以及结点之间的关系。图5-5(a)是一棵完全二叉树,图5-5(b)给出的图5-5(a)所示的完全二叉树的顺序存储结构。

 (a)  一棵完全二叉树                  (b)    顺序存储结构

图5-5 完全二叉树的顺序存储示意图

    对于一般的二叉树,如果仍按从上至下和从左到右的顺序将树中的结点顺序存储在一维数组中,则数组元素下标之间的关系不能够反映二叉树中结点之间的逻辑关系,只有增添一些并不存在的空结点,使之成为一棵完全二叉树的形式,然后再用一维数组顺序存储。如图5-6给出了一棵一般二叉树改造后的完全二叉树形态和其顺序存储状态示意图。显然,这种存储对于需增加许多空结点才能将一棵二叉树改造成为一棵完全二叉树的存储时,会造成空间的大量浪费,不宜用顺序存储结构。最坏的情况是右单支树,如图5-7 所示,一棵深度为k的右单支树,只有k个结点,却需分配2^k-1个存储单元。

(a) 一棵二叉树                          (b) 改造后的完全二叉树

(c) 改造后完全二叉树顺序存储状态

图5-6 一般二叉树及其顺序存储示意图

 (a) 一棵右单支二叉树      (b) 改造后的右单支树对应的完全二叉树

    (c) 单支树改造后完全二叉树的顺序存储状态

                   图5-7 右单支二叉树及其顺序存储示意图

    结构5-1二叉树的顺序存储

复制代码
#define Maxsize 100     //假设一维数组最多存放100个元素
typedef char Datatype;  //假设二叉树元素的数据类型为字符
typedef struct
{ Datatype bt[Maxsize];int btnum;}Btseq;
复制代码

2.链式存储结构

    二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。

通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。其结点结构为:

  其中,data域存放某结点的数据信息;lchild与rchild分别存放指向左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号∧或NULL表示)。利用这样的结点结构表示的二叉树的链式存储结构被称为二叉链表,如图5-8所示。  

(a) 一棵二叉树                           (b) 二叉链表存储结构

                  图5-8   二叉树的二叉链表表示示意图

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

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

    图5-9给出了图5-8 (a)所示的一棵二叉树的三叉链表表示。

 图5-9二叉树的三叉链表表示示意图

    尽管在二叉链表中无法由结点直接找到其双亲,但由于二叉链表结构灵活,操作方便,对于一般情况的二叉树,甚至比顺序存储结构还节省空间。因此,二叉链表是最常用的二叉树存储方式。

结构5-2二叉树的链式存储

#define datatype char  //定义二叉树元素的数据类型为字符
typedef struct  node   //定义结点由数据域,左右指针组成
{ Datatype data;struct node *lchild,*rchild;}Bitree;


转载于:https://www.cnblogs.com/tham/p/6827431.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/375724.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NetBpm 安装篇(1)

尊重别人劳动成果 转载注明出处&#xff1a;http://www.cnblogs.com/anbylau2130/p/3875718.html 官方主页 http://www.netbpm.org/docs/install.html 文件目录 Netbpm的两种服务器配置 1&#xff0c;CassiniWebServer CassiniWebServer.exe是轻量级的web服务器&#xff0c;相…

python将文本中的数据处理成图像(matplotlib)

使用Python的matplotlib模块可以很方便的将数据处理成图表&#xff0c;使数据更加形象、直观。 #!/usr/bin/env pythonimport matplotlib.pyplot as plt import numpy as np from mpl_toolkits.axes_grid.anchored_artists import AnchoredTexty1np.loadtxt(ReadDataCostTime.…

交叉编译android版htop

编这个东西贼烦人。 话不多说&#xff0c;直接上教程 源代码版本&#xff1a;htop-2.2.0、ncurses-6.1 编译之前要确认自己有ndk&#xff0c;从【官网】直接下载&#xff0c;下载下来解压一下就能用。 先编ncurses 编译过程 ./configure CCarm-linux-androideabi-gcc-4.9 \-…

UITableView知识梳理须知—(一)

1、UITableView掌握 1> 设置UITableView的dataSource、delegate 2> UITableView多组数据和单组数据的展示 3> UITableViewCell的常见属性 4> UITableView的性能优化&#xff08;cell的循环利用&#xff09; 5> 自定义Cell 2、什么是UITableView 在i…

Yarn中的几种状态机

1 概述 为了增大并发性&#xff0c;Yarn采用事件驱动的并发模型&#xff0c;将各种处理逻辑抽象成事件和调度器&#xff0c;将事件的处理过程用状态机表示。什么是状态机&#xff1f; 如果一个对象&#xff0c;其构成为若干个状态&#xff0c;以及触发这些状态发生相互转移的事…

分支管理(转载)

转自&#xff1a;http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013743862006503a1c5bf5a783434581661a3cc2084efa000 分支就是科幻电影里面的平行宇宙&#xff0c;当你正在电脑前努力学习Git的时候&#xff0c;另一个你正在另一个平行…

分享一个用安卓手机就能引导pc安装linux系统办法

1、首先安卓手机下载软件DriveDroid.apk http://pan.baidu.com/s/1qW4pbT6 2、下载linux镜像文件放手机存储卡存储&#xff0c;放到Download/images/以下 3、打开软件会自己主动读取这个目录以下镜像&#xff0c;也能够在软件里面下载须要的镜像文件 4、软件设置usb连接模式 5、…

SharePoint 2013 开发——其他社交功能

博客地址&#xff1a;http://blog.csdn.net/FoxDave上一篇讲了如何获取用户配置文件的相关属性&#xff0c;它属于SharePoint 2013社交功能的一个小的构成部分。社交功能是SharePoint 2013改进的一大亮点。可以在现有网站上开启社交功能或者新建一个专门用于社交用途的社区网站…

第一个Qt+opencv程序

简单安装好Qt和编译安装好opencv后&#xff0c;简单实现第一个Qtopencv程序&#xff1a;读取并显示一张图片&#xff0c;这里我的Qt版本时5.9.1&#xff0c;opencv版本是4.0.1&#xff0c;版本的影响不大。 首先我们用Qt创建一个控制台项目&#xff0c;即在创建项目时选择Qt C…

redis学习笔记——应用场景

最近在看redis入门指南&#xff0c;现在就自己的学习情况说说自己的理解。 字符串类型&#xff08;String&#xff09; 字符串类型是Redis中最基本的类型&#xff0c;能存储任意形式的字符串&#xff0c;包括二进制数据。如一张照片也可以用字符串类型存储。注意字符串类型键允…

Graphviz从入门到不精通

1、安装Graphviz &#xff08;windows 版本&#xff0c;后面说linux下的安装&#xff09; 1.1&#xff09;下载安装文件 从graphviz官网下载 http://www.graphviz.org/Download.php 或者从我的百度网盘下载 http://pan.baidu.com/s/1i3mzunV 下载后双击安装&#xff0c;跟着提示…

HDU2602 (0-1背包)

Bone Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 39259 Accepted Submission(s): 16261 Problem DescriptionMany years ago , in Teddy’s hometown there was a man who was called “Bone Col…

博客3万访问量了……

博客有3万访问量了呢。自从第一次用了赠送的1500的流量券&#xff0c;粉丝了从零突破了&#xff0c;到现在有150个粉丝了。 之前预想的写博客的初衷&#xff0c;也是记录自己的学习过程&#xff0c;毕竟好记忆不如烂笔头&#xff0c;记录下来就是长长久久的&#xff0c;随时可以…

循环多少次?

循环多少次&#xff1f; Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 17 Accepted Submission(s) : 12 Problem Description我们知道&#xff0c;在编程中&#xff0c;我们时常需要考虑到时间复杂度&#xff0…

【Java】Java里String 的equals和==

Java里面有对象和对象的引用的概念&#xff0c;在String方面&#xff0c;比较的是引用&#xff0c;equals比较的是对象的具体值。 String s1 new String("abc");String s2 new String("abc");System.out.println(s1 s2);System.out.println(s1.equals(s…

[bootstrap] 打造一个简单的系统模板(1) 左侧折叠菜单

1. 前言 最近需要做一个后台管理系统&#xff0c;我打算使用bootstrap弄一个好看的后台模板。网上的好多模板我觉的css和js有点重。 于是就打算完全依靠bootstrap搭建一个属于自己的模板。 首先从左侧的折叠菜单开始。看图。 2. CSS 代码 以下是自定义的css代码&#xff0c;由于…

How Many Shortest Path

zoj2760:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode2760 题意&#xff1a;给你一张有向带权图&#xff0c;然后问你最短路径有多少条。 题解&#xff1a;这一题用到了网络流&#xff0c;一开始&#xff0c;我想到用找到一条最短路&#xff0c;然后删除这条…

人物角色群体攻击判定二(叉乘来判断敌人的位置)

建议阅读: 判断敌人在玩家的某一个区域: http://www.cnblogs.com/plateFace/p/4716799.html 我们可以根据玩家和敌人的坐标, 进行叉乘来获取一个向量可以用它来判断敌人的位置, 敌人是否在攻击范围内. 下面我简单实现下对单体敌人是否攻击做判定 这种方式有一种重大的BUG, 假设…

HDU 5371 Manacher Hotaru's problem

求出一个连续子序列&#xff0c;这个子序列由三部分ABC构成&#xff0c;其中AB是回文串&#xff0c;A和C相同&#xff0c;也就是BC也是回文串。 求这样一个最长的子序列。 Manacher算法是在所有两个相邻数字之间插入一个特殊的数字&#xff0c;比如-1&#xff0c; Manacher算法…

平庸技术流,用 WebApi +AngularJS 实现网络爬虫

最近园子里网络爬虫很火爆&#xff0c;从 PHP 到 Python&#xff0c;从 windows服务 到 winform 程序&#xff0c;各路大神各显神通。小弟也献下丑&#xff0c;从平庸流出发&#xff0c;简述下 WebApi AngularJS 方式实现网络爬虫。 一、技术框架 1.1 前端&#xff1a; Angular…