精华内容
下载资源
问答
  • 二叉树

    2021-08-11 17:51:43
    定义:树是一个有n个元素的集合,当n=0时,这是个空树,在一个非空树中,有一个根节点(root),它没有前驱节点,除根节点外的其他元素被分成的每个不相交的集合都是一棵树。 二叉树 1. 二叉树定义: 跟树的...


     

    树与二叉树

     树

    定义:树是一个有n个元素的集合,当n=0时,这是个空树,在一个非空树中,有一个根节点(root),它没有前驱节点,除根节点外的其他元素被分成的每个不相交的集合都是一棵树。

    二叉树

     1. 二叉树定义:
        
        跟树的定义类似,但一个双亲节点最多只有两个子节点,一个叫左子树,一个叫右子树。
        一个结点指向另一个结点就是双亲节点,因为前者衍生了后者,从前驱节点才能找到后继节点,是不是觉得前驱后继很眼熟吗?单链表也是一种特殊的树结构,后继节点就是子节点。因为一个节点也是棵树,所以我们管他叫左子树,和右子树。左右是人为规定划分的,一颗二叉树的左右子树互换后是一颗新的二叉树。
        
        
         
     2. 满二叉树与完全二叉树定义:
    满二叉树的意思是:所有非叶子节点,既有左孩子,又有右孩子,所有叶子节点都在同一层(叶子节点是指没有孩子的节点)
    完全二叉树的意思是:叶子节点只能存在树的最底层,和最底层的上一层,最底层的上一层的所有非叶子节点的右孩子若不为空,则左孩子一定不为空,左孩子若为空,右孩子无所谓。且完全二叉树存在节点的序号跟满二叉树的节点序号是相同的。
     3. 

    二叉树的五条性质
    性质1 一颗二叉树上的第n层最多有2^{k-1}个节点|
    性质2一个深度为k的二叉树,最多有2^{k}-1个节点
    性质3对于一颗非空二叉树,节点的孩子数为2的节点数+1=叶子节点个数
    性质4具有n个节点的完全二叉树的深度为\left \lfloor log2^{n} \right \rfloor+1
    性质5如果按从上到下从左到右从1开始编号,完全二叉树的双亲节点是孩子节点编号/2下去整,左孩子是双亲节点编号的两倍,右孩子是两倍+

     

    解释说明:

    1因为,第一层最多是一个根节点,第二层最多是两个孩子,第三层最多是四个,所以第n层是2^{n-1}

    2因为完全二叉树 ,若只有根节点则是1个,若有两层,则是1+2=3个,三层则是1+2+4=7,所以n层是,2^{n}-1

    3 这个结论是可以证明的,因为一棵树的节点总个数n,可以按节点的度(孩子个数)划分节点,所以n=n0+n2+n1 ,有得节点度为1,有得节点度为2,还有度为0的点。从另一种角度去想,我有一个度为2的点是不是会发出两个分支,一个度为1的点会发出一个分支,但是除了根节点,没有节点能让根节点做分支,所以n=n1+2*n2+1 前后两个式子联立就解得该性质3

    4通过性质1 和性质2 可知,层数为k的二叉树中 总结点个数 n ,满足2^{k-1}< n\leq 2^{k}-1,前者是只有一层的情况下满足,后者是满二叉树的情况下满足,对其取对数求解得到性质四

    二叉树的存储

    顺序存储
    #define MAX_TREE_SIZE 100    //二叉树的最大节点数
    typedef TElemType SqBiTree[MAX_TREE_SIZE+1]
    
    从一号单元当做根节点,假设一个节点的位置为n,则左孩子为2n,右孩子为2n+1
    
    链式存储
    typedef struct BiTNode{
        TElemType data;                //待存入数据的类型
        strcuct BiTNode *lchild,*rchild;//指向左孩子和右孩子的指针 可以加个parent指针,使得节点不再是单方向的了
    }BTNode,*BiTree;
    
    

    二叉树的遍历

    三种遍历方式 先中后,这里的先中后 指的是根的顺序,孩子的顺序默认是先左后右
    
    先序遍历
    
    访问该节点
    
    自递归左子树
    
    自递归右子树
    
    中序遍历
    
    自递归左子树
    
    访问该节点
    
    自递归右子树
    
    后序遍历
    
    自递归左子树
    
    自递归右子树
    
    访问该节点

    二叉树的层序遍历

    就是根节点入队,访问后出队,把左右孩子入队,接着访问队首元素,然后队首元素出队,然后左右孩子入队,就能实现层序遍历

    线索二叉树

            一颗二叉树有n个节点,如果是链式二叉树,有2n个指针,但是只有n-1个存储了孩子地址,所以可以利用剩下的指针,对二叉树进行 前中后三种顺序的线索化找到,按三种顺序遍历的前驱节点,增加两个标志,代表这里到底存储的是孩子还是线索,然后按需要的逻辑 给该节点若有空指针找到该节点按先中后三序变化的前驱节点,就完成了线索化,线索化后的二叉树没有空指针。

    二叉树和森林的转化

    用孩子兄弟法去转换,二叉树的左孩子还是左孩子,兄弟做森林的右孩子,就可以吧一颗二叉树拆成森林。

    二叉树的前中序遍历和其转化的森林的前中序遍历得到的结果相同

    哈夫曼树与霍夫曼编码

    其实哈夫曼树很简单,我用电脑自带的画图给大家模拟一下哈夫曼树的建立过程大家立马就明白,咱也不会做动画,大家凑活凑活看,肯定能看懂

     

     

     

     

     

     哈夫曼树就是每次都选择两颗最小的子树合并成一颗新的树

    霍夫曼编码的目的是为了压缩,根据一篇文章出现的字母数量,出现一次给权值+1 让出现的少的先合并,然后哈夫曼树左分支代表0右分支代表1,用这个01编码串代表这个字母,就可以令出现次数多的字母以较少的01代码串表示,从而实现压缩的目的

    展开全文
  • 二叉树

    2021-04-17 21:02:11
    二叉树定义和基本术语二叉树二叉树性质二叉树存储顺序存储结构链式存储结构二叉树结点数据类型定义二叉树的遍历遍历算法还原二叉树二叉搜索缺点平衡二叉树 定义和基本术语 (Tree)是n(n>=0)个结点的...

    定义和基本术语

    (Tree)是n(n>=0)个结点的有限集。树形结构是一类(1:n)非线性数据结构。
    树
    如上图所示,每个结点都可以从根节点经过一个唯一的弧序列到达,此弧序列被称为路径,路径中的弧的个数称为路径长度。(结点也可写作节点)

    树

    1. (Root)结点是没有父结点的结点;
    2. 结点的(Degree):一个结点含有的子树的个数称为该结点的度;树的度:树中所有结点的度的最大值;
    3. 叶结点(Leaf):度为0的结点称为叶结点,也可以叫做终端结点
    4. 分支结点:度不为0的结点称为分支结点,也可以叫做非终端结点
    5. 孩子(Child):一个结点子树的根结点称为该结点的孩子结点;这个结点称为孩子结点的 双亲(父结点Parent);
    6. 兄弟(Sibling):同一双亲结点的孩子结点间互称兄弟结点;堂兄弟:双亲在同一层次的结点互为堂兄弟;
    7. 祖先:从根结点到该结点所经分支上的所有结点都是此结点的祖先; 子孙:以某结点为根的子树中的所有结点都是该结点的子孙;
    8. 结点的层次(Level):从根结点开始,根结点的层次为1,根的直接后继层次为2以此类推; 结点的层序编号:将树中的结点,按照从上层到下层,同层从左到右的次序排成一个线性序列,把他们编成连续的自然数;
    9. 树的高度(深度Depth):树中结点的最大层次;
    10. 森林(Forest):m(m>=0)个互不相交的树的集合,将一颗非空树的根结点删去,树就变成一个森林;给森林增加一个统一的根结点,森林就变成一棵树;

    二叉树

    二叉树(Binary Tree)是至多有两个子结点的树,每一个子节点都区分左右且不能颠倒顺序,左边子节点称为左子结点,右边子结点称为右子结点
    满二叉树:一颗深度为k且有 2 k − 1 2^k-1 2k1个结点的二叉树称为满二叉树(每一层的结点都达到最大值)。
    在这里插入图片描述
    完全二叉树:叶子结点只可能在最下面的两侧上;对于任一结点,其右分支下的子孙最大层数为 l l l, 其左分支子孙最大层数必为 l + 1 l+1 l+1

    完全二叉树

    二叉树性质

    1. 在二叉树的第i层上至多有2^(i-1)个结点(i≥1);
    2. 深度为k的二叉树的 最大节点数为 2 k − 1 2^k-1 2k1个;
    3. 任何一棵二叉树T,如果终端点结点数为n0,度为2的结点数n2,则n0 = n2+1;
    4. 具有n个结点的完全二叉树的深度为 ⌊ l o g 2 n ⌋ + 1 ⌊log_2^n⌋+1 log2n+1;
    5. 如果一棵树有n个结点按层序编号(从第1层到 ⌊ l o g 2 n ⌋ + 1 ⌊log_2^n⌋+1 log2n+1层,每层从左到右),对于任意结点i,有:(1)如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲PARENT(i)= ⌊ i / 2 ⌋ ⌊i/2⌋ i/2;(2)如果2i>n,则结点i为叶子节点(没有左孩子);否则其左孩子LCHILD(i)=2i;(3)如果2i+1>n,则结点i无右孩子结点;否则其右孩子RCHILD(i)=2i+1。

    二叉树存储

    顺序存储结构

    按照自上而下,从左到右给整个二叉树编号,(不是完全二叉树一律转为完全二叉树,即如果结点为空也要给编号),然后以编号为下标存入数组中。这种存储对于满二叉树和完全二叉树可以做到唯一复原,而且不会浪费空间,但如果不是满二叉树和完全二叉树将会浪费很大存储空间。
    在这里插入图片描述

    链式存储结构

    用二叉链表从根节点开始存储,当然访问也要从根节点开始访问。
    在这里插入图片描述

    二叉树结点数据类型定义

    typedef struct node *tree_pointer;
    typedef struct node {
    	int data;
    	tree_pointer left_child;
    	tree_pointer right_child;
    } node;
    
    /**
     * LeetCode: Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    

    二叉树的遍历

    二叉树由根、左子树、右子树构成,定义为D、L、R的组合共有六种遍历方案:LDR、LRD、DLR、DRL、RDL、RLD,在限定先左后右后,有三种方案:DLR(先序遍历)、LDR(中序遍历)、LRD后序遍历) 。——可以看的出,“先、中、后”是按照访问结点D先于子树还是后于子树出现。
    层次遍历:逐层从左到右遍历整个二叉树。(可以利用队列存放子树的指针)
    在这里插入图片描述二叉树遍历的时间复杂度和空间复杂度都是 O ( n ) O(n) O(n)

    遍历算法

    一般遍历算法采用递归来做格外简单

    void PreOrderTraverve(node *root)
    {  // 先序遍历
    	if(root != NULL){
    		std::cout << root->data;
    		PreOrderTraverve(root->left_child);
    		PreOrderTraverve(root->right_child);
    	}
    }
    
    void InOrderTraverve(node *root)
    {  // 中序遍历
    	if(root != NULL){
    		PreOrderTraverve(root->left_child);
    		std::cout << root->data;
    		PreOrderTraverve(root->right_child);
    	}
    }
    
    void PostOrderTraverve(node *root)
    {
    	if(root != NULL){
    		PreOrderTraverve(root->left_child);
    		PreOrderTraverve(root->right_child);
    		std::cout << root->data;
    	}
    }
    

    还原二叉树

    给定 先序+中序 or 后序+中序可以唯一确定一颗二叉树而 先序+后序 不能。

    先序遍历的根节点在前,中序遍历根节点左边是左子树的结点,右边是右子树的结点,后续遍历的根节点在最后。
    所以给定前序+中序,根据前序遍历特点拿出先序序列第一个结点(先序第一个结点是根节点),将中序序列分为两段(左子树)根(左子树),继续重复直到还原。给定中序+后序,根据后序遍历特点,拿出后序序列最后结点(后序最后一个结点是根节点),将中序分为两段(左子树)根(左子树)`,继续重复直到还原。
    还原二叉树

    二叉搜索树 BST

    二叉搜索树(Binary Search Tree),又名二叉排序树、有序二叉树、二叉查找树,是一颗空树或者具有下列特点的树:

    1. 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
    2. 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
    3. 任意节点的左、右子树也分别为二叉查找树。
    4. 没有键值相等的节点。

    重要性质:二叉搜索树的中序遍历是一个有序数组。如不同形态的二叉查找树(a)中序遍历:6、8、10、11、13、14、15、17

    缺点

    二叉查找树比普通的树查找更快,插入、删除、查找的时间复杂度为 O ( l o g 2 n ) O(log_2^n) O(log2n),但当用有序数列创建一颗二叉搜索树时有可能生成一个单分支的二叉树,退化为一种线性链表似的结构了,它的查找时间复杂度还是 O ( n ) O(n) O(n),所以出现了平衡二叉树。

    二叉搜索树不同形态

    BST的操作有构建、插入、查找、删除等,这里不做实现,但是会实现平衡二叉树。
    二叉搜索树的实现可以参考: 二叉搜索树详解(C++实现)

    平衡二叉树

    定义

    平衡二叉树(Balanced Binary Tree)又称为AVL树,它是二叉树搜索树的改进,使得二叉树尽量降低高度,保持高度平衡,减少树的平均搜索长度。它是具有以下特点的二叉搜索树:

    • 它是一颗空树或它的左右子树高度差绝不能超过1;
    • 左右子树也必须是平衡二叉树

    ——关于AVL,AVL是大学教授G.M. Adelson-Velsky 和 E.M. Landis 名称的缩写,他们提出的平衡二叉树的概念,为了纪念他们,将 平衡二叉树 称为 AVL树。

    在AVL树中,任何结点的左右子树高度最大差别是1,为了度量高度差引入了下边的一个概念,平衡因子。

    平衡因子 balance factor
    平 衡 因 子 = 结 点 左 子 树 高 度 − 结 点 右 子 树 高 度 平衡因子=结点左子树高度-结点右子树高度 =

    当然,平衡因子(bf)也可以是右子树高度减去左子树高低,为了统一我这里用左子树高度-右子树高低。

    在AVL树中,平衡因子必须满足: 1 > = b f > = − 1 1>=bf >=-1 1>=bf>=1, 否则就不是AVL树了。

    在这里插入图片描述由AVL树的定义,上图不是AVL树。

    在这里插入图片描述

    破坏平衡情况

    在介绍AVL操作之前先来看看破坏平衡的四种情况。大致可以分为两种,内测和外侧,其中外侧包括左左型和右右型,内测包括左右型和右左型。

    左左型——右旋

    在这里插入图片描述

    在平衡状态下,给一个结点(T)的左左孩子(X)插入子结点(M),导致结点(T)平衡因子不符合AVL树要求,这种情况是左左型,需要降低左子树的高度,进行右旋转

    右旋步骤:

    1. 以L为圆形,T向右旋转成为L的右孩子;(T>L,T可以作为L的右孩子)
    2. L原来的右孩子Y变为T的左孩子。 (T>Y>L,Y可以作为T的左孩子)

    在这里插入图片描述

    注意:旋转以平衡因子被破坏的节点作为T。
    其实Y可以是虚结点,当Y是一个虚结点的时候,插入M之前整个二叉树也是平衡的。

    右旋动图展示:

    在这里插入图片描述

    右右型——左旋

    在这里插入图片描述

    在平衡状态下,给一个结点(T)的右右孩子(X)插入子结点(M),导致结点(T)平衡因子不符合AVL树要求,这种情况是右右型,需要降低右子树的高度,进行左旋转
    很容易看出,右右型和左左型是对称的,它们同是在AVL的外侧结点(X)插入子结点导致失衡。

    左旋步骤:

    1. 以R为圆形,T向左旋转成为R的左孩子;(T<R,T可以作为R的左孩子)
    2. R原来的左孩子Y变为T的右孩子。 (T<Y<R,Y可以作为T的右孩子)

    在这里插入图片描述
    左旋动图展示:
    在这里插入图片描述

    左旋和右旋对称,相同的,Y也可以是虚结点。
    如果Y是虚结点,那么在插入新的结点M后,R的平衡因子bf=-2, T的平衡因子也是-2,但是我们旋转选择距离插入节点更远的根节点T来做旋转。

    左右型——左旋+右旋

    在这里插入图片描述左右型如果仅仅使用右旋转是不平衡的。
    在这里插入图片描述需要经过一个左旋将内测高度降低、外侧高度增加,然后在进行右旋降低左子树高度即可。
    步骤:

    • 以L结点进行左旋,完成左旋后在把R作为T的左子结点;(N>R>M>L,所以M可以作为L的右孩子)
    • 以T结点进行右旋。

    在这里插入图片描述

    插入的结点时M或者N,这里进行左旋的时候要注意是以T的左孩子结点L为根进行的;
    左旋和右旋比较重要,先以L为根进行左旋,在以T为根进行右旋,如果看不清楚可以将左旋、右旋的图和上图进行比较,建议自己在纸上多画几次。

    右左型——右旋+左旋

    右左型和左右型对称,需要先以T的右孩子进行右旋,将右内测的高度降低、升高右外侧的高度,然后在以T为根进行左旋,完成平衡。

    在这里插入图片描述

    AVL操作

    AVL树的的操作和BST的操作基本相同,只是在插入删除的时候AVL需要通过旋转保持树的平衡。

    插入

    插入的时候从根结点开始,小就往左走,大就往右走,(注意不能相等)直到插入到合适的位置,如果是BST到这里就结束了,但是AVL需要根据新节点的位置进行四种不同的旋转以保证可以达到平衡。

    查找

    查找是从根节点开始,小就往左走,大就往右走,如果相等就返回,如果到达叶子节点还没找到就查找失败。

    注意:AVL树由于加了平衡,查找的复杂度 O ( l o g 2 n ) O(log_2^n) O(log2n),这是它同BST的优势所在。

    删除

    平衡二叉树结点的删除比较复杂,主要取决于删除了结点之后是否平衡,如果失衡还要做出相应的调整。

    主要把删除的结点分为三类:
    (1) 叶子节点 (度为0的结点)
    (2) 只有左子树或只有右子树(即删除的结点是度为1的结点)
    (3) 既有左子树又有右子树(度为2的节点)

    (1)当删除的节点是叶子节点,则将节点删除,然后从父节点开始,判断是否失衡,如果没有失衡,则再判断父节点的父节点是否失衡,直到根节点,此时到根节点还发现没有失衡,则说此时树是平衡的;如果中间过程发现失衡,则判断属于哪种类型的失衡(左左,左右,右左,右右),然后进行调整。

    (2)删除的节点只有左子树或只有右子树,这种情况其实就比删除叶子节点的步骤多一步,就是将节点删除,然后把仅有一支的左子树或右子树替代原有结点的位置,后面的步骤就一样了,从父节点开始,判断是否失衡,如果没有失衡,则再判断父节点的父节点是否失衡,直到根节点,如果中间过程发现失衡,则根据失衡的类型进行调整。

    (3)删除的节点既有左子树又有右子树,这种情况又比上面这种多一步,就是中序遍历,找到待删除节点的前驱或者后驱都行,然后与待删除节点互换位置,然后把待删除的节点删掉,后面的步骤也是一样,判断是否失衡,然后根据失衡类型进行调整。

    中序遍历

    同二叉树的中序遍历,先访问左子树,然后访问根最后在访问右子树,一般调用递归比较简单。

    二叉搜索树的中序遍历是升序排列的,所以格外重要。

    AVL的实现可以参考:STL源码笔记(18)—平衡二叉树AVL(C++封装+模板)


    参考:

    1. 数据结构 —— 图解AVL树(平衡二叉树)
    2. 二叉查找树与平衡二叉树
    3. 种树:二叉树、二叉搜索树、AVL树、红黑树、哈夫曼树、B树、树与森林

    说明:图片来自网络和以上博客,如有侵权请联系删除

    展开全文
  • 一、二叉树到多叉 结构是为了方便快捷的实现查找操作的,的高度是命中查找的一个不可抗拒的时间下限。在一定的数据条件下,的高度和宽度是互相制约的。(就像一定面积下,矩形的长和宽是互相制约的。) ...

    一、二叉树到多叉树

    树结构是为了方便快捷的实现查找操作的,树的高度是命中查找的一个不可抗拒的时间下限。在一定的数据条件下,树的高度和宽度是互相制约的。(就像一定面积下,矩形的长和宽是互相制约的。)

    二叉树尽管简单易于实现,实际中构造出来的树的高度很很高的,不利于查找,也就有了我们上一篇中关于平衡二叉树的内容,那么如何能降低树的高度呢?这就需要引入多叉树,通过加大树的宽度来降低其高度

     

    二、多叉树

    二叉树中每个结点有一个数据项,最多有两个子结点,如果允许每个结点有多个数据项和多个子结点,那么这个树就是多叉树.

    树的每个节点可以有两个以上的子节点,称为m阶的多叉树,或者称为m叉树。

    性质

    • 每个节点有m个子节点和m-1个键值。
    • 每个节点中的键值按升序排列。
    • 前i个子节点中的键值都小于第i个键值。
    • 后m-1个子节点中的键值都大于第i个键值。

    典型的多叉树有2-3-4-Tree, B-Tree.

    3、2-3-4-Tree

    2-3-4-Tree是多叉树,它的每个节点最多有四个子节点和三个数据项。

    2-3-4树像红黑树一样是平衡树。它的效率比红黑树稍差,但是编程容易。是红黑树的基础

    上图展示的就是一棵2-3-4树,每个节点可以保存一个、两个或者三个数据项。 
    上图中上面三个节点有子节点,底层的六个节点都是叶节点,没有子节点。2-3-4树中所有的叶节点都是在一层上的。

    3.1、2-3-4树名字的含义


    2-3-4树中的2、3、4的含义指的是一个节点可能含有的子节点数。对非子叶节点有三种可能的情况: 
           · 有一个数据项的节点总是有两个子节点 
           · 有两个数据项的节点总是有三个子节点 
           · 有三个数据项的节点重是有四个子节点 
           上述的重要的关系决定了2-3-4树的结构,比较而言,叶节点没有子节点,然而他可能还有一个、两个、三个数据项。空节点是不会存在的。在2-3-4树中不允许只有一个连接。有一个数据项的节点必须总是保持两个连接,除非它是叶节点,在那种情况下没有连接。

    3.2、2-3-4树的组织


    为了方便起见,用从 0 到 2 的数据给数据项编号,用 0 到 3 给子节点编号,从左到右升序。 
           树结构中很重要的一点就是它的链与自己的数据项的关键字值之间的关系。2-3-4树中的规则和二叉树的规则大体一样,但是还加上了以下几点:下面的情况指的是有三个数据项且有四个子节点的情况: 
           · 根是 child0 的子树的所有子节点的关键字值小于key0; 
           · 根是 child1 的子树的所有子节点的关键字值大于key0并且小于key1; 
           · 根是 child2 的子树的所有子节点的关键字值大于key1并且小于key2; 
           · 根是 child3 的子树的所有子节点的关键字值大于key2。

    3.3、2-3-4树的查找


           查找特定的关键字值的数据项和在二叉树中的搜索例程很类似。从根开始,除非要查找的关键字值就是根,否则选择关键字值所在的合适范围,转向那个方向,知道找到为止。

    最多做树的高度次查找即可

    3.4、2-3-4树插入数据


    新的数据项插入总是在叶节点里,在树的最底层。如果插入到有子节点的节点里,子节点的编号就要发生变·化以此来保持树的结构,这保证了节点的子节点比数据项多1。


    2-3-4树中插入节点都是从查找适当的叶节点开始的。一般有两种情况: 
    (1)查找时没有碰到满节点时,插入很简单。找到合适的叶节点后,只要把新数据项插入进去就可以了。如上面插入B,X 
    (2)如果插入节点已经满了,插入可能会涉及到在一个节点中移动一个或者两个其他的数据项,这样才能保证在新数据项插入后关键值仍保持正确的顺序。这就涉及到节点大的分裂。正是这种分裂的过程保证了树的平衡。 如上面插入H的时候。

    3.4.1、节点分裂:

    把要分裂节点中的数据项设为A、B、C,下面时分裂时的情况。(假设要分裂的节点不是根) 
    要进行下面的步骤: 
           · 创建一个新的空节点,它是要分裂节点的兄弟,在要分裂节点的右边 
           · 数据项C移到新节点中 
           · 数据项B移到要分裂节点的父节点中 
           · 数据项A保留在原来的位置 
           · 最右边的两个子节点从要分裂处断节点处断开,连到新节点上 

    3.4.2、根的分裂

    如果一开始查找插入点时就碰到满的根时,插入过程更加复杂一点: 
           · 创建新的根,它是要分裂节点的父节点 
           · 创建第二个新节点,它是要分裂节点的兄弟节点 
           · 数据项C移到新的兄弟节点中 
           · 数据项B移到新的根节点中 
           · 数据项A保留在原来的位置上 
           · 要分裂节点的最右边的两个子节点断开连接,连到新的兄弟节点中 

     

    3.5、删除操作

    (1)如果2-3-4树中不存在当前需要删除的key,则删除失败。

    (2)如果当前需要删除的key不位于叶子节点上,则用后继key覆盖,然后在它后继key所在的子支中删除该后继key。

    (3)如果当前需要删除的key位于叶子节点上:

           (3.1)该节点不是2节点,删除key,结束

           (3.2)该节点是2节点,删除该节点:

                  (3.2.1)如果兄弟节点不是2节点,则父节点中的key下移到该节点,兄弟节点中的一个key上移

                 (3.2.2)如果兄弟节点是2节点,父节点是个3节点或4节点,父节点中的key与兄弟节点合并

                 (3.2.3)如果兄弟节点是2节点,父节点是个2节点,父节点中的key与兄弟节点中的key合并,形成一个3节点,把此节点看成当前节点(此节点实际上是下一层的节点),重复步骤3.2.1到3.2.3

       如果是在2节点(叶子节点)中进行删除,每次删除会减少一个分支,如果删除操作导致根节点参与合并,则2-3-4树会降低一层。

    image


    image

    image


    image


    image

    4、从2-3-4树到红黑树

    2-3-4树的分裂和红黑树的插入是完全一致的

    将已知的节点都涂成黑色,对于其中的三个节点FGJ,将中间G提上去,这时多了G到F,G到J,将这些新增的涂成红色

    这样新的到的一个二叉树有红色黑色的就是红黑树

    对于得到的2-3-4树,通过三条规则可以把2-3-4树转化为红黑树 

    2-3-4树和红黑树的等价关系

    如果一棵树满足红黑树,把红结点收缩到其父结点,就变成了2-3-4树,所有红色节点都与其父节点构成3或4节点,其它节点为2节点。图中NIL节点未画出。

    image_thumb53

    所以红黑树的每一类型操作都与2-3-4树一一对应。黑色节点的个数(或者说位置)对应2-3-4树中的节点个数(或者说位置),这样可以很好的理解性质3(从每个叶子到根的所有路径上不能有两个连续的红色节点)和性质5(从任一节点到它所能到达得叶子节点的所有简单路径都包含相同数目的黑色节点)以及根节点到任意叶子节点的路径长度,最多相差一半

    同时我们还需要明白的是,一颗红黑树对应唯一形态的2-3-4树,但是一颗2-3-4树可以对应多种形态的红黑树(主要是3节点可以对应两种不同的红黑树形态),上图中的2-3-4树还可以对应下图中的红黑树。我们在后面红黑树的删除操作中会利用这种情况。

    image_thumb54

    5、红黑树的定义

    2-3-4树和红黑树是完全等价的,由于绝大多数编程语言直接实现2-3-4树会非常繁琐,所以一般是通过实现红黑树来实现替代2-3-4树,而红黑树本也同样保证在O(lgn)的时间内完成查找、插入和删除操作。

    红黑树是每个节点都带有颜色属性的平衡二叉查找树 ,颜色为红色或黑色。除了二叉查找树一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:

    (1) 节点是要么红色或要么是黑色。

    (2) 根一定是黑色节点。

    (3) 每个叶子结点都带有两个空的黑色结点(称之为NIL节点,它又被称为黑哨兵)。

    (4) 每个红色节点的两个子节点都是黑色(或者说从每个叶子到根的所有路径上不能有两个连续的红色节点)。

    (5) 从任一节点到它所能到达得叶子节点的所有简单路径都包含相同数目的黑色节点。

    这些性质保证了根节点到任意叶子节点的路径长度,最多相差一半(因为路径上的黑色节点相等,差别只是不能相邻的红色节点个数),所以红黑树是一个基本平衡的二叉搜索树,它没有AVL树那么绝对平衡,但是同样的关键字组成的红黑树相比AVL旋转操作要少,而且删除操作也比AVL树效率更高,实际应用效果也比AVL树更出众。当然红黑树的具体实现也复杂的多。

    image_thumb55

    红黑树的这5个性质中,第3点是比较难理解的,但它却非常有必要。我们看上面这张图,如果不使用黑哨兵,它完全满足红黑树性质,根结点5到两个叶结点1和叶结点9路径上的黑色结点数都为3个,且没有连续红色节点。

    但如果加入黑哨兵后,叶结点的个数变为8个黑哨兵,根结点5到这8个叶结点路径上的黑高度就不一样了,所以它并不是一棵红黑树。NIL节点的存在还可以使得红黑树在代码实现方面得到简化,在具体实现过程中我们只需要1个NIL节点即可,详情请关注本博客的下一篇文章,有关红黑树代码的实现。

     

    image_thumb52

    红黑树的所有性质其实都可以从2-3-4树来理解,这也是理解红黑树最好的方式,因为红黑树本质就是2-3-4树。

    https://blog.csdn.net/v_july_v/article/details/6109153

    https://blog.csdn.net/v_july_v/article/details/6530142

    6、2-3-4树的效率

    2-3-4树中增加每一个节点的数据项数量可以抵偿树的高度的减少。

    2-3-4树中的查找时间与平衡二叉树如红黑树大概相等,都是O(logN).

     

    7、待补充

     

    展开全文
  • 从树二叉树入门

    2021-10-15 18:45:40
    堆是一种特殊的完全二叉树。堆的特点是,它满足:它的每一个父节点都父节点的值大于它的两个子节点的值 或者 它的每一个父节点都父节点的值小于它的两个子节点的值。若它的根为最大值则称之为大根堆,若它的根为堆...

    1.树是什么?

    之所以被称之为树,是因为其结构神似一棵倒挂着的树。

    而一棵树是由零到多个节点所构成的,而我们使用父子关系形容相连节点之间的关系。例如下图中的“3”和“4”节点,“3”节点被称为“4”节点的父节点,而“4”节点被称为“3”节点的子节点。也就是说,在相连的两个节点之间,处于上方的节点被称为处于下方的节点的父节点,而处于下方的节点被称为上方节点的子节点。

    一个节点含有的子节点的个数被称为该节点的度。

    没有父节点的节点被称为根节点。一棵树最多只有一个根节点,而在逻辑结构图中则表示为最上方的节点,也就是“3”节点是这棵树的根节点。并且,子树之间不能相交。除了根节点,其他节点有且仅有一个父节点。

    下面我们联系上图介绍一些关于树的重要的基本概念:

     一个节点的子节点个数被称为该节点的度。如图中的“6”节点的度为2。

    度为0的节点被称为叶子节点。如图中的“2”,“8”,“9”,“1"都是叶子节点。

    一棵树的最大层次被称之为该树的高度或者深度。例如上图的树的高度为4。

     了解完了树的基本概念,我们来进一步理解二叉树是什么。

     2.二叉树入门

    2.1二叉树的概念

    二叉树是一种特殊的树。

    其结构特点为一颗二叉树由根节点与其称为左子树、右子树的二叉树构成。

    并且,二叉树可以为空。

     从结构特点出发,我们知道:二叉树的所有节点的度都不大于2。

    一棵二叉树可能有几种存在情况:

     而二叉树中,存在特殊的情况:

    2.2特殊的二叉树

    满二叉树

    若一棵树的每一层的节点数都达到最大值,则称该二叉树为满二叉树。

    完全二叉树

    将一棵树从上到下,从左到右从1开始给每个节点编号,若其编号为i的节点与一颗满二叉树中编号为i的节点所处的位置相同,则该二叉树称为完全二叉树。

    要理解完全二叉树,我们通过画图进行解释:

    我们先将一棵树从上到下,从左到右从1开始给每个节点编号

     接着,我们画出一个高度为3的满二叉树。

     很明显,我们所画的树编号为5的节点与满二叉树中编号为5的节点的位置并不相同,根据定义,只要有一个节点不能与满二叉树对应,该二叉树就不是完全二叉树。

    但是如果5的节点的位置改变:

    可以看到,新的二叉树的所有节点的编号都能与满二叉树的编号相同,那么新的二叉树就是一棵完全二叉树。

    此外,二叉树还有一些需要我们了解的基本性质:

    2.3二叉树的基本性质

    1.若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(n-1)个结点。

    2.若规定根节点的层数为1,则深度为h的二叉树最多节点数为2^h-1。

    3.对任何一棵二叉树而言,度为0的节点数量(设为n0) 等于 度为2的节点数量(设为n2) + 1。即n0=n2+1。

    4.对于具有n个节点的满二叉树,若规定根节点的层数为1,则其高度h=log(2)(n+1)  (log(2)(n+1)指log以2为底以n+1为对数)。

    2.4二叉树的储存结构

    最后,我们来了解二叉树是如何储存的。

    二叉树一般有两种储存方式:顺序结构和链式结构。

    二叉树的顺序存储

    顺序储存指的是用数组来表示二叉树,但是一般只有完全二叉树才会采用数组的方式来存储,因为非完全二叉树会存在空间上的浪费。

    二叉树的链式存储

    链式存储是指用链表来表示二叉树。 表示的方法分为三叉链表和二叉链表,这里我们介绍二叉链表。在二叉链表中,每个节点由三个部分组成:该节点左子节点的地址、该节点右子节点的地址以及保存的数据。

     用结构体表示每个节点:

    typedef int TreeDataType;
    struct TreeNode
    {
    	struct TreeNode* left;
    	struct TreeNode* right;
    	TreeDataType a;
    };

    展开全文
  • ,二叉树

    2019-09-20 16:54:33
    首先我们来了解什么是? 看下图,了一棵:
  • 红黑参考 太牛了,这个漫画,讲的通俗易懂。 参考 https://baijiahao.baidu.com/s?id=1641940303518144126&wfr=spider&for=pc
  • 二叉树(一)

    千次阅读 2019-12-30 15:56:55
    文章目录的定义结点的定义的其它概念二叉树的定义满二叉树完全二叉树二叉树的性质性质1性质2性质3性质4性质5二叉树的存储结构二叉树的顺序存储结构二叉树的链式存储结构 本篇文章将讲解二叉树,因为和...
  • 二叉树

    2020-06-19 12:07:32
    应该是数据结构中最难的吧, 复习到这块做二叉树的练习题, 不是很好做, 大部分都是递归题, 的考点也很多。 首先要区分和森林, 其次又分为二叉树和非二叉树。 我们主要以二叉树为主复习, 因为往年考点较...
  • 当n=0时,空树 2).当n≠0时,非空树 2.1)有且仅有一个结点 2.2)除根节点外的其余结点可分为m(m>0)个互不相交的有限集,T1,T2,…,Tm,其中每一个集合本身又是一棵树,并称为根的子树 树的表示形式 1).维恩图。即...
  • 数据结构之二叉树逻辑结构树树的基本概念的基本术语的性质小结二叉树特殊二叉树二叉树完全二叉树二叉排序平衡二叉树二叉树的性质...中序遍历后序遍历层次遍历线索二叉树树、森林、二叉树的转换及遍历...
  • 是我们常用的数据结构,如堆、二叉搜索、B等,它们都有自己的特点,使得我们在程序设计中常常使用。下面就说说的基础知识,二叉树和完全二叉树。并用java使用链表描述完全二叉树
  • 二叉树

    2021-02-20 22:34:29
    n=0 时称为 空树。 在任意一棵非空树中:(1)有且仅有一个特定的称为 根(Root)的节点。 (2):当 n>1 时, 其余节点(除了根节点)可分为 m( m>0) 个 互不相交的有限集 T1, T2, ......,Tm , 其中 每一个...
  • 文章目录概述一、的定义二、的基本术语三、为什么要研究二叉树四、二叉树的区别五、二叉树的定义六、二叉树的不同形态小结 概述 非线性结构元素的前驱和后继的个数不是为1的,这一节讲的形结构元素的前驱...
  • 二叉树定义二叉树的创建二叉树的前中后序遍历前序遍历:中序遍历后序遍历已知前序、中序遍历结果,还原二叉树已知后序、中序遍历结果,还原二叉树二叉树的层序遍历二叉搜索二叉搜索是什么?构造二叉搜索代码...
  • (1)二叉树(Binary Tree)是一个有限元素的集合(可以),它或者是空二叉树),或者由一个称为根的元素以及分别称为左子树和右子的两个互不相交的集合组成,这个两个集合又都是二叉树。 上面这个定义太...
  • 二叉树(二)

    千次阅读 2020-01-01 12:50:32
    上篇文章介绍了二叉树的定义以及遍历方式。 本篇文章将讲解二叉树的算法实现。 二叉树的遍历算法 先序遍历算法 先序遍历的实现方式在前面已经说过了,比如下面的一棵二叉树: 我们需要先访问根结点A,然后以...
  • 1. 有一颗的括号表示为A(B, C(E, F(G)), D),回答下面的问题:指出的根结点?指出棵的所有叶子结点?结点C的度是多少?这棵的度为多少?这棵的高度是多少?结点C的孩子结点是哪?结点C的双亲结点是谁?...
  • 二叉树习题

    2019-12-06 01:13:18
    知识点:二叉树的有序性 ...h最小则为满二叉树,一棵10层的有1024个节点,则1025个节点最少为11层。最高1025层,串成了一串。 在一棵度为4的T中,若有20个度为4的结点,10个度为3的结点,1个度为...
  • 二叉树的应用

    2021-05-09 16:28:16
    二叉树的应用 实验内容 基本要求: 算法:输入字符序列,建立二叉树;按先序、中序、后序遍历二叉树(三种递归算法和中序遍历的非递归算法); 拟遍历的二叉树(此处出你计划遍历的二叉树和此二叉树对应的二叉...
  • 二叉树学习

    2019-10-08 17:56:44
    二叉树是每个结点最多有两个子树的结构 1.2:二叉树的五种基本形态和两种特殊形态: 五种基本形态: 两种特殊形态: 1.3:二叉树的性质: A、在二叉树的第i层上最多有2^(i-1)个结点(i>=1)。B、...
  • 数据结构编程笔记十五:第六章 二叉树 二叉树的转换算法实现 哈夫曼等各种二叉树、满二叉树、完全二叉树、二叉排序(二叉查找... 3 分钟理解完全二叉树、平衡二叉树、二叉查找 - ......
  • 数据结构 二叉树

    2019-04-25 02:50:53
    文章目录概述术语(Tree)的定义二叉树(Binary Tree)特殊形态完全二叉树(Complete Binary Tree)的性质满二叉树(Full Binary Tree)的性质二叉树的性质二叉树的存储结构顺序存储链式存储C实现二叉树的遍历C实现 ...
  • 数据结构与算法整理7——二叉树(C语言) 目录 数据结构与算法整理7——二叉树(C语言) ...后,画树 3、哈夫曼算法及哈夫曼编码,WPL的计算 3.1 哈夫曼相关概念 3.2 哈夫曼的构造 ...
  • 二叉树、查找算法总结 目录二叉树、查找算法总结前言一、的定义二、二叉树1.定义2.二叉树的存储结构3.拥有特殊形态的二叉树三.二叉树的遍历1.先序遍历2.中序遍历3.后序遍历4.层次遍历四.线索二叉树概念五...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,861
精华内容 5,144
关键字:

从空树画二叉树