2.二叉树-基本概念

二叉树
高度:根节点的高度最高(从0开始算起)
深度:根节点的深度最浅(从0开始算起)
层:根节点的层数最小(从1开始算起)
在这里插入图片描述
二叉树中有两种比较特殊的二叉树:

完全二叉树:叶子节点都在最底下两层,最后一层的叶子节点都靠左排列,并且除了最后一层,其他层的节点个数都要达到最大
满二叉树:叶子节点全都在最底层,除了叶子节点之外,每个节点都有左右两 个子节点

二叉树的存储最直观的是链式存储法:

class Node{
	int data;
	Node left;
	Node right;
}

在这里插入图片描述
基于数组的顺序存储法:
我们把根节点存储在下标 i = 1 的位置,那左子节点存储在下标 2 * i = 2 的位置,右子节点存储在 2 * i + 1 = 3 的位置。以此类推,B 节点的左子节点存储在 2 * i = 2 * 2 = 4 的位置,右子节点存储在 2 * i + 1 = 2 * 2 + 1 = 5。根节点一般不存在下标为0的位置,因为这样的话,左节点就是i2+1,右子节点存储在i2+2的位置,计算的时候不方便计算,左右子树都有一个加法。
在这里插入图片描述
基于数组的顺序存储方法存储非完全二叉式的时候会浪费很多空间。这也是为什么完全
二叉树会单独拎出来的原因,也是为什么完全二叉树要求最后一层的子节点都靠左的原因。

二叉树的前、中、后序,表示的是节点与它的左右子树节点遍历打印的先后顺序(根节点的打印时机)。
前序遍历是指,对于树中的任意节点来说,先打印这个节点,然后再打印它的左子树,最后
打印它的右子树。
中序遍历是指,对于树中的任意节点来说,先打印它的左子树,然后再打印它本身,最后打
印它的右子树。
后序遍历是指,对于树中的任意节点来说,先打印它的左子树,然后再打印它的右子树,最
后打印这个节点本身。
在这里插入图片描述
实际上,二叉树的前、中、后序遍历就是一个递归的过程。比如,前序遍历,其实就是先打印根
节点,然后再递归地打印左子树,最后递归地打印右子树。
写递归代码的关键,就是看能不能写出递推公式,而写递推公式的关键就是,如果要解决问题
A,就假设子问题 B、C 已经解决,然后再来看如何利用 B、C 来解决 A。所以,我们可以把
前、中、后序遍历的递推公式都写出来。

preOrder(Tree)=print(data)->preOrder(Tree.left)->preOrder(Tree.right)
inOrder(Tree)=inOrder(Tree.left)->print(data)->inOrder(Tree.right)
postOrder(Tree)=postOrder(Tree.left)->postOrder(Tree.right)->print(data)

从前面画的前、中、后序遍历的顺序图,可以看出来,每个节点最多会被访问两次,所以遍历
操作的时间复杂度,跟节点的个数 n 成正比,也就是说二叉树遍历的时间复杂度是 O(n)。

特殊的二叉树

特殊的的二叉树,二叉查找树。二叉查找树最大的特点就是,支持动态数据集合的快速插入、删除、查找操作。
极端情况下二叉树会退化成为链表。
所以说又出现了平衡二叉查找树。

平衡二叉树的严格定义是:二叉树中的任何一个节点的左右子树的高度相差不能大于1

所以说完全二叉树一定是平衡二叉树,非完全二叉树也有可能是平衡树。
在这里插入图片描述

再加上查找二字则是:在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值

平衡二叉查找树的数据结构实现有很多种,如:

  • AVL树
  • 红黑树(不满足上面的平衡二叉树的绝对定义)
  • 伸展树(Splay Tree),树堆(Treap)等等。

由此又延展出了平衡多叉查找树数据结构,如:

  • B树(B-树)
  • B+树
  • B*树(B+树的变种)

二叉树增加,删除,删除的复杂度是的O(log n)
散列表增加,删除,删除的复杂度是的O(1)

但是散列表的底层是数组存储的数据,所以涉及到扩容,缩容并不方便
在加上散列函数的设计,冲突解决办法等,要考虑的东西很多。如果考虑上散列冲突,这个O(1)并不比常量小。再加上hash函数的耗时,效率并不一定很高。另外散列表中的数据是无序的,所以排列输出比较不方便。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 二叉树和树的基本概念 二叉树是一种特殊的树形数据结构,每个节点最多只有两个子节点,分别称为左子节点和右子节点。树是由节点和边组成的,其中树的顶部节点称为节点,而树的最底部节点称为叶节点。 2. 二叉树的存储结构 二叉树可以使用链式存储方式或顺序存储方式。链式存储方式是通过指针来连接每个节点,顺序存储方式是通过数组来存储每个节点的值,可以使用完全二叉树的方式来存储。 3. 二叉树的基本算法 (1)二叉树的遍历 二叉树的遍历方式包括前序遍历、中序遍历和后序遍历。其中前序遍历是指先遍历节点,再遍历左子树,最后遍历右子树;中序遍历是指先遍历左子树,再遍历节点,最后遍历右子树;后序遍历是指先遍历左子树,再遍历右子树,最后遍历节点。 (2)二叉树的查找 二叉树的查找可以使用递归算法或非递归算法。递归算法是通过比较节点值来判断遍历方向,非递归算法可以使用栈或队列来实现。 (3)二叉树的插入和删除 二叉树的插入和删除操作可以通过递归算法或非递归算法来实现。插入操作可以先进行查找操作,再将节点插入到合适的位置;删除操作需要分为三种情况:删除叶子节点、删除只有一个子节点节点和删除有两个子节点节点。 (4)二叉树的非递归遍历算法 二叉树的非递归遍历算法可以使用栈来实现。以前序遍历为例,首先将节点入栈,然后弹出栈顶节点并输出,再将右子节点入栈,最后将左子节点入栈。重复以上操作,直到栈为空。中序遍历和后序遍历可以使用类似的方式实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值