树的一些认识

树的一些概念

树是一种数据结构;
树是由节点(node)和边(edge)组成的无环结构;
单个结点是一棵树,树根就是该结点本身;
空集合也是树,称为空树,空树中没有结点;

设T1,T2,…,Tk是树,它们的根结点分别为n1,n2,…,nk。用一个新结点n作为n1,n2,…,nk的父亲,则得到一棵新树,结点n就是新树的根。我们称n1,n2,…,nk为一组兄弟结点,它们都是结点n的子结点。我们还称T1,T2,…,Tk为结点n的子树。

名称解释
结点的度一个结点含有的子结点的个数
叶子结点度为 0 的结点,也叫终端结点
双亲结点若一个结点有子结点,则这个结点就是其子结点的双亲结点,也叫父节点
孩子结点一个结点含有的子树的根结点称为该结点的孩子结点,也叫子结点
兄弟结点具有相同父结点的结点互称为兄弟结点
结点深度从树的根结点到该结点的边的个数
结点高度该结点和某个叶子之间存在最长路径上的边的个数
树的高度根结点的高度
树的层次根结点的层次为 0,它的孩子为 1,依次类推

树的类型

名称解释
无序树树中任意节点的子结点之间没有顺序关系的树
有序树树中任意节点的子结点之间有顺序关系的树
二叉树每个节点最多含有两个子树的树

以下主要是对常见树的介绍,相关文章可以自行搜索查看

二叉树的类型

满二叉树

A Full Binary Tree (FBT) is a tree in which every node other than the leaves has two children.
除了叶子结点之外的每一个结点都有两个孩子结点

在这里插入图片描述

完全二叉树

A Complete Binary Tree (CBT) is a binary tree in which every level, except possibly the last, is completely filled, and all nodes are as far left as possible.
除了最后一层之外的其他每一层都被完全填充,并且所有结点都保持向左对齐

在这里插入图片描述

完美二叉树

Every node except the leaf nodes have two children and every level (last level too) is completely filled
除了叶子结点之外的每一个结点都有两个孩子,每一层(当然包含最后一层)都被完全填充。

在这里插入图片描述


平衡二叉树

平衡二叉树又称 AVL 树,它是空树或者它的左右两颗子树的高度差的绝对值不超过 1,且左右两颗子树都是平衡二叉树。

实现过程

为了保证二叉树平衡,平衡二叉树会在某一部分不平衡度超过一个阈值后采取平衡操作,保证其平衡性。

平衡因子:某个结点的左子树的高度减去右子树的高度得到的差值。

// 我们定义二叉树的数据结构
struct Node {
    int data;
    int height;
    struct Node* left;
    struct Node* right;
};

using NodePtr = struct Node*;
树的平衡化操作

二叉树的平衡化有两大基础操作: 左旋和右旋。

左旋操作

B 结点和 A 结点父子交换,A 结点成为 B 结点的左孩子,C 结点不变。当 B 结点已经有左孩子时,通常是将 B 结点的左孩子丢弃,然后让丢弃的左孩子成为 A 结点的右孩子
在这里插入图片描述

NodePtr rotateLeft(NodePtr root) {
    NodePtr right = root->right;
    root->right = right->left;
    right->left = root;

    right->left->height = max(alvHeight(right->left->left), alvHeight(right->left->right)) + 1;
    right->height = max(alvHeight(right->left), alvHeight(right->right)) + 1;

    return right;
}
右旋操作

B 结点和 A 结点父子交换,A 结点成为 B 结点的右孩子,C 结点不变。当 B 结点已经有右孩子时,通常是将 B 结点的右孩子丢弃,然后让丢弃的右孩子成为 A 结点的左孩子

在这里插入图片描述

NodePtr rotateRight(NodePtr root) {
    NodePtr left = root->left;
    root->left = left->right;
    left->right = root;

    left->right->height = max(alvHeight(left->right->left), alvHeight(left->right->right)) + 1;
    left->height = max(alvHeight(left->left), alvHeight(left->right)) + 1;

    return left;
}

平衡操作代码

NodePtr balance(NodePtr root) {
    int factor = getBalanceFactor(root);
    // LL
    if(factor > 1 && getBalanceFactor(root->left) > 0)
        return rotateRight(root);
    //LR
    else if(factor > 1 && getBalanceFactor(root->left) <= 0) { 
        root->left = rotateLeft(root->left);
        return rotateRight(root);
    // RR
    } else if(factor < -1 && getBalanceFactor(root->right) <= 0) 
        return rotateLeft(root);
    // RL
    else if((factor < -1 && getBalanceFactor(root->right) > 0)) { 
        root->right = rotateRight(root->right);
        return rotateLeft(root);
    } else {
        return root;
    }
}

红黑树

红黑树是一种含有红黑结点并能自平衡的二叉查找树。它必须满足下面性质:

  • 每个节点要么是黑色,要么是红色。
  • 根节点是黑色。
  • 每个叶子节点(NIL)是黑色。
  • 每个红色结点的两个子结点一定都是黑色。
  • 任意一结点到每个叶子结点的路径都包含数量相同的黑结点。

红黑树应用

  • 红黑树在Linux非实时任务调度中的应用
    Linux 的稳定内核版本在 2. 6. 24 之后,使用了新的调度程序 CFS,所有非实时可运行进程都以虚拟运行时间为 key 值挂在一棵红黑树上,以完成更公平高效地调度所有任务。CFS 弃用 active /expired 数组和动态计算优先级,不再跟踪任务的睡眠时间和区别是否交互任务,并且在调度中采用基于时间计算键值的红黑树来选取下一个任务,根据所有任务占用 CPU 时间的状态来确定调度任务优先级。
  • 红黑树在Linux虚拟内存中的应用
    32 位 Linux 内核虚拟地址空间划分 0 - 3G 为用户空间,3 - 4G 为内核空间,因此每个进程可以使用 4GB的虚拟空间。同时,Linux 定义了虚拟存储区域( VMA) 以便于更好表示进程所使用的虚拟空间,每个 VMA是某个进程的一段连续虚拟空间,其中的单元具有相同的特征,所有的虚拟区域按照地址排序由指针链接为一个链表。当发生缺页中断时搜索 VMA 到指定区域时,则需要频繁操作,因此选用了红黑树以减少查找时间。
  • 红黑树在检测树的平衡性上的应用
    红黑树是一种自平衡二叉搜索树,它的每个节点都被“着色”为红色或者黑色,这些节点的颜色被用来检测树的平衡性。红黑树作为嵌入式数据库中的索引机制,可以获得更好的性能,对于SQLite数据库,可以采用红黑树实现索引机制的优化

B 树/B+树/B*树

  • B树是一种自平衡的树,一个节点可以拥有2个以上的子节点。
  • B树能够保持数据有序。这种数据结构能够让查找数据、顺序访问、插入数据及删除的动作,都在对数时间内完成。
  • B树适用于读写相对大的数据块的存储系统,例如磁盘。
    B树减少定位记录时所经历的中间过程,从而加快存取速度
  • B树这种数据结构可以用来描述外部存储,常被应用在数据库文件系统的实现上。

B+ 树在 B 树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+ 树总是到叶子结点才命中。

B* 树在 B+ 树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从 1/2 提高到 2/3;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值