数据结构与算法6: 树的基本概念及性质
来源:互联网 发布:hadoop元数据是什么 编辑:程序博客网 时间:2024/05/21 09:37
本节总结树相关的基本概念、性质。
1. 树的定义
树(递归定义): 满足以下3个条件的结构是树:
(1) 空结构是一棵树;
(2)如果t1,t2,⋯,tk 是不相交的树,那么,根节点以t1,t2,⋯,tk 作为子节点的数据结构也是一棵树;
(3) 只有通过1和2产生的数据结构才是树。
注意与树相关的一些基本概念。
度: 一个结点拥有的子树数目称为结点的度。
叶子: 度为0的结点称为叶子或者终端节点。
非终端节点:度不为0的节点称为非终端节点或者分支节点;除根以外的分支节点称为内部节点。
要注意树的层次和深度的概念。
层次(Level): 结点的层次是从根开始定义起,根为第一层,根的孩子为第二层,依次递推。
深度(Depth): 树中结点的最大层次称为树的深度。
2. 二叉树类别
二叉树(Binary Tree): 二叉树是一种特殊的树,它的特点如下:
1) 每个结点至多有两棵子树,即不存在度大于2的结点
2)二叉树的子树有左右之分,其顺序不能任意颠倒
满二叉树: 一棵深度为k且有
完全二叉树: 深度为k,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n(从上而下,从左至右对满二叉树编号,编号从1开始算起)的节点一一对应时,称之为完全二叉树。
二叉搜索树(Binary Search Tree):二叉查找树,也称二叉搜索树、有序二叉树(ordered binary tree),排序二叉树(sorted binary tree)。它或者是一棵空树;或者是指具有如下性质的二叉树:
(1)若它的左子树不为空,则左子树上所有的节点的值均小于它的根节点的值 (2) 若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值(3) 它的左、右子树也分别为二叉搜索树。
例如二叉搜索树如下图所示:
平衡二叉树(Balanced Binary Tree): 也称AVL树(由发明者Georgy Adelson-Velsky和E. M. Landis的名字字母命名)。平衡二叉树或者是一棵空树,或者是具有如下性质的二叉树:
它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。
平衡因子(Balance Factor): 在平衡二叉树中,每个节点的平衡因子定义为该节点的左子树的深度减去它的右子树的深度。对于平衡二叉树,所有结点的平衡因子只可能是-1,0,1三个值。只要二叉树上有一个节点的平衡因子的绝对值大于1,则该二叉树就是不平衡的。
伸展树(Splay Tree): 与平衡二叉树不同,伸展树并不总是在局部重新构造平衡树(AVL树)或者全局重新创建平衡树(DSW算法),伸展树的策略是将常用的元素向上移动,重新指定为根,从而形成一种“优先树”。
二叉堆(Binary Heap): 二叉堆是堆的一种常见实现。二叉堆可以看做是有两个约束的二叉树(可参见维基百科binary heap):
(1)形态约束
二叉堆是完全二叉树,树的所有层中,除了最后一层外,其余所有层都被填满,如果最后一层没有填满,则节点必定是从左至右排列的。
(2) 数据约束
每个节点都大于等于(大顶堆)或者小于等于(小顶堆)它的每个子节点的值。
堆可以由数组实现。形态上是一棵完全二叉树,但是与二叉搜索树不同的是,中序遍历时元素并不一定保持有序。n个元素的序列
ki≤k2i 并且ki≤k2i+1 (小顶堆 min heap)
或者:
ki≥k2i 并且ki≥k2i+1 (大顶堆 max heap)
注意:堆中的元素并没有正确排序。例如大顶堆,我们只知道最大的元素在根节点中,对于每个节点而言,其所有的后继结点都小于或者等于该节点。但是,同辈之间、叔侄之间的关系并未确定。
例如大顶堆如下图所示:
3.树的性质
在总结二叉树的性质基础上,推广到多叉树。
1)k层结点计数性质 : 在二叉树上第k层上,至多有
可利用数学归纳法证明。
对于m叉树,第k层上的节点,至多为
例如3叉树如下图所示:
2)二叉树结点计数性质: 在深度为k的二叉树上至多有
可通过等比数列计算得到。
深度为k的m叉树上结点数目至多为:
3)度的关系计算性质:
二叉树中除了根节点以外,每个节点都有一个分支进入,因此,总的节点数目满足(其中
结点数目n=
n0+n1+n2
结点数目n=分支数目+1。 其中分支数目=2×n2+n1
有上述关系可以得到:
利用分支数目和树的节点数目的关系来进行计算是关键。
对于多叉树也可以利用这个关系进行计算。
4)完全二叉树的高度计算
具有n个结点的完全二叉树的深度为:
其中向下取整函数,表示不超过x的整数中最大的一个,定义为:
这个性质可以利用完全二叉树和满二叉树的结点个数性质证明之。
5)完全二叉树父节点和孩子关系计算
如果有n个结点的完全二叉树,对任一结点
- 如果
i=1 ,则i 为根,无双亲;若i>1 ,则i 的双亲为⌊i/2⌋ 。 - 如果
2i>n ,则无左孩子,否则左孩子为2i ; - 如果
2i+1>n ,则无右孩子,否则右孩子为2i+1
4. 二叉树中的旋转操作
旋转操作是很多算法中的基本操作,旋转操作包括左旋转和右旋转。如下图所示(摘自维基百科):
动态效果图如下:
左旋转和右旋转这种说法,也并不统一,一般可以通过将右旋转记为绕着p顺时针旋转,左旋转记为绕着q逆时针旋转。
定义节点为:
/** * 二叉树搜索树结点类BSTNode * 暂时处理整型数据 */class BSTNode {public: BSTNode(const int& e,BSTNode*p ,BSTNode *l=0,BSTNode *r=0) :key(e),height(1) ,parent(p), left(l),right(r){ }private: int key; int height; // 以这个结点为根的树的高度 BSTNode *parent,*left,*right;};
则左旋转和右旋转的实现代码如下:
/** * 以p->right为支点 左旋转 * 注意更新指针指向和结点的高度 * p q * / \ / \ * s q => p qr * / \ / \ * ql qr s ql */void BST::leftRotate(BSTNode* p) { BSTNode *q = p->right, *g=p->parent; p->right = q->left; if(q->left != 0) q->left->parent = p; q->left = p; p->parent = q; q->parent = g; p->height = calcHeight(p); q->height = calcHeight(q); if(g == 0) root = q; // 设置新的根节点 else if(p == g->left) g->left = q; else g->right = q;}/** * 以p->left为支点 右旋转 * 注意更新指针指向和结点的高度 * p q * / \ / \ * q s => ql p * / \ / \ * ql qr qr s */void BST::rightRotate(BSTNode* p) { BSTNode* q = p->left,*g=p->parent; p->left = q->right; if(q->right != 0) q->right->parent = p; q->right = p; p->parent = q; q->parent = g; p->height = calcHeight(p); q->height = calcHeight(q); if(g == 0) root = q; else if(p == g->left) g->left = q; else g->right = q;}
5.多叉搜索树
m阶多叉搜索树: 又称m叉搜索树,它具有如下特性:
(1) 每个节点有m个子节点和m-1个键值
(2) 每个节点中,键值按升序排列
(3) 前i个子节点中键值都小于第i个键值
(4) 后m-i个子节点中键值都大于第i个键值。
例如4叉搜索树如下图所示:
B-Tree: m阶的B树具有下列特性的多叉搜索树:
(1) 根节点至少有两个子树,除非它是一个叶节点
(2) 每个非根非叶节点都有k-1个键值和k个指向子树的指针
其中键的数目k-1的上下界为:[⌈m/2⌉−1,m−1 ] ,例如5阶的B-Tree,键数目为[2,4]。
(3) 每个叶节点都含有k-1个键值,k-1需要满足上下界要求
(4) 所有的叶节点在同一层
B-Tree的阶,可以理解为孩子节点的最大数目。
例如5阶B-Tree如下图所示:
- 数据结构与算法6: 树的基本概念及性质
- 树的基本概念及性质
- 树的基本概念与性质
- 《数据结构与算法》之二叉树的性质
- 7.1 树的基本概念、性质与运算
- 数据结构与算法的基本概念
- 算法与数据结构的基本概念
- java数据结构与算法之树基本概念及二叉树(BinaryTree)的设计与实现
- java数据结构与算法之树基本概念及二叉树(BinaryTree)的设计与实现
- 二叉树基本概念及性质
- 数据结构与算法专题之树——树与二叉树的定义与性质
- 二叉搜索树的基本概念、性质及Python实现
- 数据结构与算法 基本概念
- 数据结构与算法 基本概念
- 数据结构与算法系列-树-二叉树的定义与性质
- 数据结构与算法系列-树-数的基本概念
- python数据结构与算法 36 树的基本概念
- 树与二叉树基本概念与性质
- ARM Linux内核驱动异常定位方法分析--反汇编方式
- XIB使用小技巧
- Mac 终端显示[进程已完成]解决办法
- 关于uIP的移植以及部分特性解析和勘误
- 异常处理
- 数据结构与算法6: 树的基本概念及性质
- asp.net 后台拼接table横向显示
- X3.2discuz 发帖步骤
- mac:在当前文件中打开终端
- SD
- 从微信自定义菜单说php json_encode不转义中文汉字的方法
- 红包随机算法
- Android初学------系统设置之设置输入法
- MySQL增加Sequence管理功能