▎前言
小编菜归菜,但是好歹也写过几篇关于树的博客:、、。
如果你已经会了这些树,那么你一定会认为树很麻烦,很烧脑。
其中的红黑树是一种二叉排序树实现自平衡的树,但是最烦人,线段树和划分树都很好写,而红黑树不仅要建树、查找,还要再实现自平衡。
但是虚二叉树和红黑树功能一样,只不过更大的优点在于计数,却免去了建树和实现自平衡的过程。
▎虚二叉树
☞『定义』
这个东西在百度上找不着定义。
通常的静态二叉排序树,需要先构造一棵空树,而虚二叉树巧妙的结合了二分法,省略掉了这个过程。
由于不直接去构造二叉树,所以便失去了二叉树的外显形式,因此我们称之为:虚二叉树。
说白了就是免去建树的静态二叉排序树,所以说是“虚”二叉树。
☞『算法核心』
在我们对一个有序的数列进行二分查找时,实际上就相当于对一棵二叉树进行查找。
例如下面就是一个二分查找的示例程序:
1 int search(int x) 2 { 3 int l=1,r=n; 4 while(l<=r) 5 { 6 int mid=(l+r)>>1; 7 if(v[mid]==x) return mid; 8 if(v[mid]>x) r=mid-1; 9 else l=mid+1;10 } 11 }
其中我们不难发现mid始终就是[l,r]区间的中点,类似于二叉树中的根。
而左边[l,mid-1]则形成了其左子树形态。
右边[mid+1,r]则形成了其右子树的形态。
这棵二叉树就是虚二叉树。
相信用过树的大家应该都知道使用数组完全是靠节点编号关系来判断的,所以根不一定是最中间的,但是虚二叉树的根是在中间的。
虚二叉树虽然不是近似满二叉树,也没有静态二叉排序树那样完美的结构,但是却是天然的平衡二叉树,由二分查找的过程知道最多查找log n次即可,因此虚二叉树和平衡二叉树的时间复杂度相差无几,却大大降低了代码复杂度。
☞『不同』
虚二叉树不就是二分查找吗?相信你早已开始吐槽了。
其实虚二叉树与二分查找不一样,最大的不同正是它的优点。
在实现静态二叉排序树时,我们就会把所有的需要修改的量都保留在根节点上,虚二叉树也可以这样做,每棵子树的根节点实际上就是mid,那么我们就可以在mid上保留信息了。
其实这一个不同和虚二叉树的用途有关,虚二叉树可以利用这一点统计个数。
☞『优点』
我们只要想象这棵二叉树长什么样,理解就不困难了。
这样的的虚实现省去了构造,实现上就得以进一步简化。