二叉树和二叉堆

本文介绍了二叉树的基本概念,包括满二叉树和完全二叉树的定义,以及二叉树的性质,如结点数量的计算。此外,文章详细阐述了二叉树的遍历方法,包括前序、中序和后续遍历,并提到利用栈实现非递归遍历的可能性。同时,讨论了如何将普通树转化为二叉树以及二叉树的计数问题。接着,文章转向二叉堆,解释了二叉堆作为完全二叉树的数组表示形式,以及最大(最小)二叉堆的性质,并探讨了其在数据处理中的应用,如排序。

一、二叉树
1.基本概念
  二叉树是一个特殊的树,其中每个结点最多只能有两个子结点,也可以为空树。二叉树每个结点最多两个孩子,也就最多只能有两个子树,分别称为左、右子树,左、右子孩子。
  一棵树中除了叶子节点外,其余所有结点都有两个孩子,称为满二叉树。而如果由一个满二叉树缺失掉最高层级的最右端部分结点的树,称为完全二叉树。对于完全二叉树,叶子结点只会出现在最高的两个层级,且如果一个结点有左孩子结点,那么它必定有右孩子结点。
2.性质
(1)二叉树的第i层上,最多只能有2^(i-1)次方个结点。
  因为二叉树的特性,所以每层上最多就会是2的次方个结点,第一层是根结点,只有一个(2^0),第二层有2²⁻¹个,依次得到此结论。
(2)深度为k的二叉树至多有2^k-1个结点。
  同(1),总结点数即所有层级的结点数加起来,即20+21+22+……+2(n-1)=2^n-1.
(3)对任意一棵二叉树,如果其叶子节点数为n0,度为2的结点数为n2,则一定存在n0=n2+1。
  其实和第二个性质有相通之处。假设在一个深度为n的满二叉树中,度为二的结点数为2(n-2),叶子结点数为2(n-1),所以2(n-2)+1=2(n-2)。而若不是满二叉树,在统计结点数时,如果存在某个结点只有一个孩子结点,这样的结点并不在这一性质的计数范围内,所以可以直接看作其父亲结点的孩子结点是他的孩子结点。如果画出图来,就是将这个处于n层且只有一个孩子结点的结点抹去,而把其处于n+1层级的孩子结点拼接到处于n-1层的父亲结点上。最终会得到一个不存在有一个孩子结点的结点的二叉树。这个二叉树,总有一些子树其实就是个满二叉树,所以整体上还会满足这一性质。
(4)具有n个结点的完全二叉树的深度为floor(log 2底n)+1。
  其实就是第二个性质反过来了,因为是个完全二叉树不见的会出现整数,所以floor再补0。
(5)一棵有n个结点的完全二叉树,对任一个结点i来说:
1)若i=1,即该结点是根结点,那么没有父结点。而i>1时,其父结点编号为i/2。
2)若2i<n,则结点i无左孩子(也无右孩子,因为该结点是叶子节点):否则,否则,左孩子结点为2i。
3)若2i+1>n,则结点i无右孩子;否则,右孩子结点为2i+1.
  这个性质的前提是会对各结点编号,而编号会让人自然而然的想到数组下标。当将其看作数组下标后,就和线段树数组下标一个道理了。毕竟,线段树本质上也就是一个二叉树,用数组存储后当然也就是二叉堆了,这一性质也就好理解了。
3.结构
  二叉树其实本质上也就是个树,所以它完全可以用表示普通树的方法来表示,只要能符合二叉树的基本概念即可。
4.二叉树的遍历
  二叉树的遍历除了先序后序遍历外,因其单个结点最多只有两个孩子结点的特点,所以又有一种特殊的遍历方法称为中序遍历。即对于一个结点先访问左子树,再访问右子树,最后访问此节点,当然,也是从根结点开始。同样,这种遍历方法也是递归的。
  不过考虑到递归函数会浪费大量内存,可以借助栈来记录待遍历的另一个子树,通过循环解决二叉树的遍历。三种遍历方式都可,不过普通树不见得方便,因为可能的兄弟结点数目没有限制。
此处还有个小结论,已知一棵二叉树的中序序列和先序与后序序列之一即可确定一棵二叉树,而已知先序序列和后序序列却不能确定一棵二叉树。
5.普通树转化二叉树
  二叉树是有序的,操作起来比普通树方便许多,所以把普通树转化成二叉树会更有利于问题的处理。怎么转化,孩子兄弟表示法。
6.二叉树计数
  从参考的书上看,只有有n个结点的二叉树有多少种,其实还可以有很多很多问题,碰到这种问题最好还是从二叉树基本的概念和性质入手,寻找一个公式(一定存在)解决。
二、堆或二叉堆
1.基本概念
  实质上就是一个完全二叉树通过数组表示出来,线段树也就是这样表示的。这样其实就是按层级表示出所有结点,而各结点在原二叉树中的关系会通过数组下标体现。
2.性质
(1)一个结点下标为i,则其父亲结点下标为i/2,其左孩子结点下标为2i,右孩子结点下标为2i+1。
(2)最大(小)二叉堆的性质就是,任何一个父亲结点的值不小(大)于其孩子结点的值。
3.应用
  之所以会出现最大(小)二叉堆或者是大(小)根堆的概念,就是因为这一结构经常还是用于数据的处理比如排序,只不过他的处理方式及数据间的关系是符合二叉树,而其物理位置关系则只是普通的数组。而像线段树,或许可以称为一个特殊的二叉堆,则更注重对于区间信息的维护,其单个结点(数组元素)存储的是代表一个区间的数据信息,并在修改部分是对不相关的进行维护。所以,二叉堆可以自己发挥能够怎么用,可以用来干什么,解决什么问题。这应该就是它作为一种数据结构的原因吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值