找回密码
 立即注册
  • QQ空间
  • 回复
  • 收藏

算法专题 之树

admin 2019-5-7 14:10 186人围观 C++相关

树是一种抽象数据类型,用来模拟具有树状结构性质的数据集合。树与线性表、栈、队列等线性结构不同,树是一种非线性结构。一棵树只有一个根结点,树(tree)是被称为结点(node)的实体的集合,是由n(n>=1)个有限节点组成的一种具有层次关系的集合。下面一起来看看吧:

预计阅读时间:8分钟

树的基本概念的组成

树的基本概念

(1)节点<node>:树中每个元素都叫节点

(2)根节点<root>:树顶端的节点称之为根节点

(3)子树<subTree>:除根节点之外,其他节点可以分为多个树的集合叫做子树

(4)节点的度:一个节点直接含有的子树的个数,称之为节点的度

(5)叶子节点(也称叶节点、终端节点):度为0的节点叫做叶子节点

(6)父节点(双亲节点):父节点就是一个节点上头的那个节点,如果一个节点包含若干子节点,那么这个节点就是这些子节点的父节点,也叫双亲节点

(7)兄弟节点:拥有相同父节点的节点互称为兄弟节点

(8)树的度:一棵树中最大节点的度称之为树的度,即树中哪个节点的子节点最多,那么这个节点的度也就是树的度

(9)节点的层次:从根这一层开始,根算1层,根的子节点算2层,一直到最下面一层

(10)树的高度、深度:

树的深度是从根节点开始、自顶向下逐层累加(根节点的高度是1)

树的高度是从叶节点开始、自底向上逐层累加(叶节点的高度是1)

虽然树的高度和深度一样,但是具体到某个节点上,其高度和深度通常不一样

(11)有序树和无序树:树中任意一个结点的各子树按从左到右是有序的,称为有序树,否则称为无序树

树的种类

树的种类较多,较为常见的树有:二叉树、满二叉树、完全二叉树、平衡二叉树、二叉查找树、B树、B-树、B+树、B*树、红黑树、哈夫曼树和trie树等

(1)二叉树:每个节点最多有两个子节点的树

(2)满二叉树:一个二叉树所有的分支节点都存在左子树与右子树,而且所有的叶子节点都在同一层上(一棵深度为k,且有2^k-1个节点的二叉树),称为满二叉树

(3)完全二叉树:只有最下面的两层结点度小于2,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树,满二叉树一定是完全二叉树,但是完全二叉树不一定是满二叉树

(4)平衡二叉树:AVL树全称G.M. Adelson-Velsky和E.M. Landis,是由两个人的人名组成,AVL树是所有节点的左右子树的高度差小于1的二叉树,空树也是平衡二叉树的一种

(5)二叉查找树:又叫二叉排序树(Binary Sort Tree)、二叉搜索树,具有下列基本性质:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值

  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值

  • 它的左、右子树也分别为二叉搜索树

  • 空树也是二叉查找树

(6)B树:即二叉搜索树,所有非叶子结点至多拥有两个儿子,所有结点存储一个关键字,非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树

(7)B-树:是一种多路搜索树(并不是二叉的),关键字集合分布在整颗树中,任何一个关键字出现且只出现在一个结点中,搜索有可能在非叶子结点结束,除根结点以外的非叶子结点,至少含有M/2个儿子,确保了结点的至少利用率,其搜索性能等价于在关键字全集内做一次二分查找

(8)B+树:B+树是B-树的变体,也是一种多路搜索树,其定义基本与B-树同,但所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的,B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找,更适合文件索引系统

(9)B*树:是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针,B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3(代替B+树的1/2)

(10)红黑树(Red-Black Tree):是二叉搜索树(Binary Search Tree)的一种改进,红黑树的每个节点上的属性除了有一个key、3个指针:parent、lchild、rchild以外,还多了一个属性:color。它只能是两种颜色:红或黑。而红黑树除了具有二叉搜索树的所有性质之外,还具有以下基本性质:

  • 根节点是黑色的

  • 空节点是黑色的(红黑树中,根节点的parent以及所有叶节点lchild、rchild都不指向NULL,而是指向一个定义好的空节点)

  • 红色节点的父、左子、右子节点都是黑色

  • 在任何一棵子树中,每一条从根节点向下走到空节点的路径上包含的黑色节点数量都相同


(11)哈夫曼树:带权路径长度达到最小的二叉树,也叫做最优二叉树,不关心树的结构,只要求带权值的路径达到最小值,哈夫曼树可能是完全二叉树也可能是满二叉树

(12)字典树(trie树):又称为单词查找树,是一种哈希树的变种,利用字符串的公共前缀来减少查询时间,最大限度的减少无谓的字符串比较,典型应用是用于统计,排序和保存大量的字符串(不仅限于字符串),经常被搜索引擎系统用于文本词频统计。trie树具有以下基本性质:

  • 根节点不包含字符,除根节点外的每一个子节点都包含一个字符

  • 从根节点到某一节点。路径上经过的字符连接起来,就是该节点对应的字符串

  • 每个节点的所有子节点包含的字符都不相同


实例解析

题目1:不同的二叉搜索树

题目描述:给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?

示例:

给出 n = 3,则有 5 种不同形态的二叉查找树:

   1           3     3      2     1

    \        /     /      / \      \

     3     2     1      1    3      2

    /     /       \                    \

   2     1         2                    3

解题思路:如果只有1个节点,很容易得到只有1种情况(f(1)=1),2个节点,也很容易得到两只有2种情况(f(2)=2),要是有3个,f(3) = f(2)f(0)+f(1)f(1)+f(0)(2),归纳可以得到如下关系( f(0)=1 ):f(n) = f(n-1)f(0) + f(n-2)f(1) + f(n-3)f(2) + ... + f(1)f(n-2) + f(n-1)f(0)

注:下面代码可左右滑动查看

    classSolution {publicintnumTrees(int n) {if(n == 0){return0; }int[] nums = newint[n+1]; nums[0] = 1;         nums[1] = 1;if(n > 1){for (int i = 2; i <= n; i++) {for (int j = 0; j < i; j++) { nums[i] += nums[j] * nums[i-1-j]; } } }return nums[n]; }}

    题目2:验证二叉搜索树

    题目描述:给定一个二叉树,判断其是否是一个有效的二叉搜索树。

    假设一个二叉搜索树具有如下特征:

    • 节点的左子树只包含小于当前节点的数。

    • 节点的右子树只包含大于当前节点的数。

    • 所有左子树和右子树自身必须也是二叉搜索树。

    示例1:

    输入:
    2
    / \
    1 3
    输出: true

    示例 2:

    输入:
    5
    / \
    1 4
      / \
      3 6
    输出: false
    解释: 输入为: [5, 1, 4, null, null, 3, 6]。
      根节点的值为 5 ,但是其右子节点值为 4 。

    解题思路:通过中序遍历判断所有的节点值是否为升序

    注:下面代码可左右滑动查看
      classSolution{ double last = -Double.MAX_VALUE;public boolean isValidBST(TreeNode root) {if (root == null) {returntrue; }if (isValidBST(root.left)) {if (last < root.val) { last = root.val;return isValidBST(root.right); } }returnfalse; }}








      ----------------------------------------------------------------------------------------------------------------------
      我们尊重原创,也注重分享,文章来源于微信公众号:JAVA万维猿圈,建议关注公众号查看原文。如若侵权请联系qter@qter.org。
      ----------------------------------------------------------------------------------------------------------------------

      鲜花

      握手

      雷人

      路过

      鸡蛋

      yafeilinux和他的朋友们微信公众号二维码

      微信公众号

      专注于Qt嵌入式Linux开发等。扫一扫立即关注。

      Qt开源社区官方QQ群二维码

      QQ交流群

      欢迎加入QQ群大家庭,一起讨论学习!

      我有话说......