种豆资源网

当前位置:首页 > 百科 > 百科综合 / 正文

二叉树

(2019-09-20 12:02:04) 百科综合
二叉树

二叉树

在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

一棵深度为k,且有2^k-1个节点的二叉树,称为满二叉树。这种树的特点是每一层上的节点数都是最大节点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。具有n个节点的完全二叉树的深度为floor(log2n)+1。深度为k的完全二叉树,至少有2k-1个叶子节点,至多有2k-1个节点。

基本介绍

  • 中文名:二叉树
  • 外文名:Binary Tree
  • 概述:计算机中数据结构的一种
  • 简介:每个结点最多有两个子树的树结构
  • 套用学科:计算机科学
  • 存储方式:顺序存储、链式存储

定义

二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根结点的度不大于2。有了根结点之后,每个顶点定义了唯一的父结点,和最多2个子结点。然而,没有足够的信息来区分左结点和右结点。如果不考虑连通性,允许图中有多个连通分量,这样的结构叫做森林。

基本概念

二叉树是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:
(1)空二叉树——如图(a);
(2)只有一个根结点的二叉树——如图(b);
二叉树
(3)只有左子树——如图(c);
(4)只有右子树——如图(d);
(5)完全二叉树——如图(e)。
注意:儘管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。

类型

(1)完全二叉树——若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
(2)满二叉树——除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
(3)平衡二叉树——平衡二叉树又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

辨析

二叉树不是树的一种特殊情形,儘管其与树有许多相似之处,但树和二叉树有两个主要差别:
1. 树中结点的最大度数没有限制,而二叉树结点的最大度数为2;
2. 树的结点无左、右之分,而二叉树的结点有左、右之分。

相关术语

树的结点(node):包含一个数据元素及若干指向子树的分支;
孩子结点(child node):结点的子树的根称为该结点的孩子;
双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;
兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;
祖先结点: 从根到该结点的所经分支上的所有结点
子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙
结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;
树的深度:树中最大的结点层
结点的度:结点子树的个数
树的度: 树中最大的结点度。
叶子结点:也叫终端结点,是度为 0 的结点;
分枝结点:度不为0的结点;
有序树:子树有序的树,如:家族树;
无序树:不考虑子树的顺序;

二叉树性质

(1) 在非空二叉树中,第i层的结点总数不超过
, i>=1;
(2) 深度为h的二叉树最多有
个结点(h>=1),最少有h个结点;
(3) 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
(4) 具有n个结点的完全二叉树的深度为
(注:[ ]表示向下取整)
(5)有N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关係:
若I为结点编号则 如果I>1,则其父结点的编号为I/2;
如果2*I<=N,则其左孩子(即左子树的根结点)的编号为2*I;若2*I>N,则无左孩子;
如果2*I+1<=N,则其右孩子的结点编号为2*I+1;若2*I+1>N,则无右孩子。
(6)给定N个节点,能构成h(N)种不同的二叉树。
h(N)为卡特兰数的第N项。h(n)=C(2*n,n)/(n+1)。
(7)设有i个枝点,I为所有枝点的道路长度总和,J为叶的道路长度总和J=I+2i

存储结构

顺序存储方式

typenode=recorddata:datatypel,r:integer;end;vartr:array[1..n]ofnode;

鍊表存储方式

typebtree=^node;node=recorddata:datatye;lchild,rchild:btree;end;

二叉树遍历

遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。
设L、D、R分别表示遍历左子树、访问根结点和遍历右子树, 则对一棵二叉树的遍历有三种情况:DLR(称为先根次序遍历),LDR(称为中根次序遍历),LRD (称为后根次序遍历)。

先序遍历

首先访问根,再先序遍历左(右)子树,最后先序遍历右(左)子树,C语言代码如下:
void XXBL(tree *root){    //DoSomethingwithroot    if(root->lchild!=NULL)        XXBL(root->lchild);    if(root->rchild!=NULL)        XXBL(root->rchild);}

中序遍历

首先中序遍历左(右)子树,再访问根,最后中序遍历右(左)子树,C语言代码如下
void ZXBL(tree *root){    if(root->lchild!=NULL)        ZXBL(root->lchild);        //Do something with root    if(root->rchild!=NULL)        ZXBL(root->rchild);}

后序遍历

首先后序遍历左(右)子树,再后序遍历右(左)子树,最后访问根,C语言代码如下
void HXBL(tree *root){    if(root->lchild!=NULL)        HXBL(root->lchild);    if(root->rchild!=NULL)        HXBL(root->rchild);        //Do something with root}

层次遍历

即按照层次访问,通常用伫列来做。访问根,访问子女,再访问子女的子女(越往后的层次越低)(两个子女的级别相同)

线索二叉树

线索二叉树(保留遍历时结点在任一序列的前驱和后继的信息):若结点有左子树,则其lchild域指示其左孩子,否则令lchild域指示其前驱;若结点有右子树,则其rchild域指示其右孩子,否则令rchild指示其后继。还需在结点结构中增加两个标誌域LTag和RTag。LTag=0时,lchild域指示结点的左孩子,LTag=1时,lchild域指示结点的前驱;RTag=0时,rchild域指示结点的右孩子,RTag=1时,rchild域指示结点的后继。以这种结点结构构成的二叉线索鍊表,鍊表作为二叉树的存储结构,叫做其中指向结点前驱和后继的指针叫做线索,加上线索的二叉树称为线索二叉树。对二叉树以某种次序遍历使其变为线索二叉树的过程叫做线索化。若对二叉树进行中序遍历,则所得的线索二叉树称为中序线索二叉树,线索鍊表称为为中序线索鍊表。线索二叉树是一种物理结构。在中序线索树找结点后继的规律是:若其右标誌为1,则右链为线索,指示其后继,否则遍历其右子树时访问的第一个结点(右子树最左下的结点)为其后继;找结点前驱的规律是:若其左标誌为1,则左链为线索,指示其前驱,否则遍历左子树时最后访问的一个结点(左子树中最右下的结点)为其前驱。
线索二叉树的存储结构线索二叉树的存储结构
在后序线索树中找到结点的后继分三种情况:
若结点是二叉树的根,则其后继为空;若结点是其双亲的右孩子,或是其双亲的左孩子且其双亲没有右子树,则其后继即为双亲结点;若结点是其双亲的左孩子,且其双亲有右子树,则其后继为双亲右子树上按后序遍历列出的第一个结点。

示例

範例二叉树:
A
B C
D E
此树的顺序结构为:ABCDE
int main(){    node* p = newnode;    node* p = head;    head = p;    string str;    cin >> str;    creat(p, str, 0)//默认根节点在str下标0的位置    return 0;}//p为树的根节点(已开闢动态记忆体),str为二叉树的顺序存储数组ABCD##E或其他顺序存储数组,r当前结点所在顺序存储数组位置void creat(node* p, string str, int r){    p->data = str[r];    if (str[r * 2 + 1] == '#' || r * 2 + 1 > str.size() - 1)p->lch = NULL;    else    {        p->lch = newnode;        creat(p->lch, str, r * 2 + 1);    }    if (str[r * 2 + 2] == '#' || r * 2 + 2 > str.size() - 1)p->rch = NULL;    else    {        p->rch = newnode;        creat(p->rch, str, r * 2 + 2);    }}

标 签

搜索
随机推荐

Powered By 种豆资源网||