标签:排序 详解 info 电脑 现在 期望 ati lse 代码
最近刚学了平衡树,然后突发奇想写几篇博客纪念一下,可能由于是刚学的缘故,还有点儿生疏,望大家海涵
说到平衡树,就不得不从基础说起,而基础,正是二叉查找树
大家观察一下下面的这棵二叉树
相信大家一眼就能发现,这棵树从左往右是递增的(也就是右儿子大于左儿子)
那么这样的一棵树有什么用呢?
就比如说图上的这个数列 12 10 15 6 13 19 2 8 14 22
如果你想找第n大的数,你明显需要冒泡或排序最坏O(n^2/2),O(nlogn);
如果数列在更改一下,那你每次都要跑这么多,电脑累死了
但如果你用上图这棵树,根据他(右儿子>自己>左儿子)的特性,可以在期望复杂度O(logn)的时间内查出一个数据
同时修改也变得简单,O(logn)的时间查找位置,O(1)的时间连边
如下图解释
这次我要插入7,我们从根节点开始
很明显,根节点大于7,那么我把7下放到左儿子
还是大,怎么办?继续下放到左儿子
这次是小了,放右儿子
右儿子又大了,我们把他往左儿子上放
但是,8这里没有左儿子
可以恭喜了,7终于找到了自己的位置,我们现在新建一个结点,连一条边,使他变为8的左儿子
当然,有重复时也很好办,在该结点加一个数量标记,告诉他有几个即可
void add(int wz,int v) { x[wz].size++; if(x[wz].val==v) { x[wz].cnt++; return; } if(x[wz].val>v) { if(x[wz].ls!=0) { add(x[wz].ls,v); } else { bnt++; x[bnt].val=v; x[bnt].size=1; x[bnt].cnt=1; x[wz].ls=bnt; } } else { if(x[wz].rs!=0) { add(x[wz].rs,v); } else { bnt++; x[bnt].val=v; x[bnt].size=1; x[bnt].cnt=1; x[wz].rs=bnt; } } }
未完待续(其实是没来得及写完),如有问题欢迎指出
标签:排序 详解 info 电脑 现在 期望 ati lse 代码
原文地址:https://www.cnblogs.com/ztz11/p/9030674.html