在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
      二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。
      二叉树的第i层至多有 2^(i-1) 个结点;
      深度为k的二叉树至多有 2^h - 1 个结点;
      对任何一棵二叉树,若其终端节点数为n0,度为2的节点数为n2,则 n0=n2+1
      一棵深度为k,且有2^k-1个节点称之为满二叉树
      深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中,序号为1至n的节点对应时,称之为完全二叉树
 
1、定义
      二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根结点的度不大于2。有了根结点之后,每个顶点定义了唯一的父结点,和最多2个子结点。然而,没有足够的信息来区分左结点和右结点。如果不考虑连通性,允许图中有多个连通分量,这样的结构叫做森林。
 
2、基本概念
      二叉树是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:
(1)空二叉树
 

(2)只有一个根结点的二叉树

(3)只有左子树
(4)只有右子树
(5)完全二叉树
      注意:尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。
 
3、类型
(1)完全二叉树:若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
(2)满二叉树:除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
(3)平衡二叉树:又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
 
4、树的相关名词
树的结点:包含一个数据元素及若干指向子树的分支;
孩子结点:结点的子树的根称为该结点的孩子;
双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;
兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;
祖先结点: 从根到该结点的所经分支上的所有结点子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙
结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;
树的深度:树中最大的结点层;
结点的度:结点子树的个数;
树的度: 树中最大的结点度。
叶子结点:也叫终端结点,是度为 0 的结点;
分枝结点:度不为0的结点;
有序树:子树有序的树,如:家族树;
无序树:不考虑子树的顺序;
 
5、二叉树的性质
(1) 在非空二叉树中,第i层的结点总数不超过2^(i-1) ,i >= 1;

 
(2) 深度为h的二叉树最多有

2^h - 1

个结点(h>=1),最少有h个结点;

(3) 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则 N0=N2+1
(4) 具有n个结点的完全二叉树的深度为log2(n+1), 由2^h - 1 = 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
 
6、存储结构
(1)顺序存储方式
  1. typenode=record
  2. data:datatype
  3. l,r:integer;
  4. end;
  5. vartr:array[..n]ofnode;
(2)链表存储方式
  1. typebtree=^node
  2. node=record
  3. data:datatye;
  4. lchild,rchild:btree;
  5. end;

7、辨析

      二叉树不是树的一种特殊情形,尽管其与树有许多相似之处,但树和二叉树有两个主要差别:
(1)树中结点的最大度数没有限制,而二叉树结点的最大度数为2;
(2)树的结点无左、右之分,而二叉树的结点有左、右之分。
(3)遍历顺序
 
      遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。
      设L、D、R分别表示遍历左子树、访问根结点和遍历右子树, 则对一棵二叉树的遍历有三种情况:DLR(称为先根次序遍历),LDR(称为中根次序遍历),LRD (称为后根次序遍历)。
 
[1]先序遍历:首先访问根,再先序遍历左(右)子树,最后先序遍历右(左)子树,C语言代码如下:
  1. void XXBL(tree*root){
  2. //DoSomethingwithroot
  3. if(root->lchild!=NULL)
  4. XXBL(root->lchild);
  5. if(root->rchild!=NULL)
  6. XXBL(root->rchild);
  7. }

[2]中序遍历:首先中序遍历左(右)子树,再访问根,最后中序遍历右(左)子树,C语言代码如下

  1. void ZXBL(tree*root)
  2. {
  3. if(root->lchild!=NULL)
  4. ZXBL(root->lchild);//DoSomethingwithroot
  5. if(root->rchild!=NULL)
  6. ZXBL(root->rchild);
  7. }

[3]后序遍历:首先后序遍历左(右)子树,再后序遍历右(左)子树,最后访问根,C语言代码如下

  1. void HXBL(tree*root){
  2. if(root->lchild!=NULL)
  3. HXBL(root->lchild);
  4. if(root->rchild!=NULL)
  5. HXBL(root->rchild);//DoSomethingwithroot
  6. }

[4]层次遍历

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

[5]线索二叉树

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

Data Structure 之 二叉树的更多相关文章

  1. CDOJ 483 Data Structure Problem DFS

    Data Structure Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/proble ...

  2. 【LeetCode】211. Add and Search Word - Data structure design 添加与搜索单词 - 数据结构设计

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:Leetcode, 力扣,211,搜索单词,前缀树,字典树 ...

  3. [LeetCode] All O`one Data Structure 全O(1)的数据结构

    Implement a data structure supporting the following operations: Inc(Key) - Inserts a new key with va ...

  4. [LeetCode] Add and Search Word - Data structure design 添加和查找单词-数据结构设计

    Design a data structure that supports the following two operations: void addWord(word) bool search(w ...

  5. [LeetCode] Two Sum III - Data structure design 两数之和之三 - 数据结构设计

    Design and implement a TwoSum class. It should support the following operations:add and find. add - ...

  6. Finger Trees: A Simple General-purpose Data Structure

    http://staff.city.ac.uk/~ross/papers/FingerTree.html Summary We present 2-3 finger trees, a function ...

  7. Mesh Data Structure in OpenCascade

    Mesh Data Structure in OpenCascade eryar@163.com 摘要Abstract:本文对网格数据结构作简要介绍,并结合使用OpenCascade中的数据结构,将网 ...

  8. ✡ leetcode 170. Two Sum III - Data structure design 设计two sum模式 --------- java

    Design and implement a TwoSum class. It should support the following operations: add and find. add - ...

  9. leetcode Add and Search Word - Data structure design

    我要在这里装个逼啦 class WordDictionary(object): def __init__(self): """ initialize your data ...

随机推荐

  1. Extjs4.2纯前台导出Excel总结

    前段时间做了两个项目,用到了Extjs4.2纯前台导出Excel,遇到很多的问题,从网上也找了很多资料,在这里总结一下,做一个记录: 使用方法: 1.下载extexcel文件包,这里可以下载http: ...

  2. 如何判断Socket连接失效

    http://cuisuqiang.iteye.com/blog/1453632 ——————————————————————————————————————————————————————————— ...

  3. Intellij IDEA 杂记

    添加JUnit File > Settings > Plugins > Browse repositories > 搜索junit ,安装JunitGenerator V2 重 ...

  4. C++拓扑排序

    安利一篇比较写的比较好的的博客... 拓扑排序的原理及其实现 我本来以为我看懂了原理就会打了,没想到因为没有手动实践过...原理实际上也没记清楚.... 一题HDU的拓扑裸题HDU 3342 我的拓扑 ...

  5. 埃氏筛法(快速筛选n以内素数的个数)

    给你一个数n,请问n以内有多少个素数?(n <= 10e7) 一般来说,要是对一个整数进行素数判断,首先想到的是写个函数判断是否为素数,然后调用这个函数,时间复杂度为O(n^(½)),但是要求n ...

  6. Synchronization in Delphi TThread class : Synchronize, Queue

    http://embarcadero.newsgroups.archived.at/public.delphi.rtl/201112/1112035763.html > Hi,>> ...

  7. Why we need interfaces in Delphi

    http://sergworks.wordpress.com/2011/12/08/why-we-need-interfaces-in-delphi/ Why we need interfaces i ...

  8. Bit Twiddling Hacks

    http://graphics.stanford.edu/~seander/bithacks.html Bit Twiddling Hacks By Sean Eron Andersonseander ...

  9. RFID Reader 线路图收集

    This 125 kHz RFID reader http://www.serasidis.gr/circuits/RFID_reader/125kHz_RFID_reader.htm http:// ...

  10. 栈上连续定义的int变量,地址相差12个字节

    在VS2010,进行调试的时候,发现连续定义的int变量,地址相差12个字节.这是为什么? 按照我们的理解,int占用4个字节,应该相差4个字节.这是因为VS2010在Debug模式下,int变量占用 ...