二叉搜索树的建立是基于他的插入算法实现的,在上一篇博文里已经讨论过,在上篇博文中二叉搜索树的建立过程中试讲新结点插入到树的最底层,如果输给的要插入数据是按照某个键值已经排好序的有序列,例如12、23、25、32、36、43、53或者反序辣么这就会出现两种极端情况,如图所示
这样建立的二叉搜索树只有单支,他的查找时间复杂度非O(n),这种情况主要是由于二叉树中结点分布不均衡导致。平衡二叉树就因此而产生。
平衡二叉树是满足以下性质的二叉排序树:
平衡二叉树或者空树;或者是具有如下特性的二叉排序树
(1)树中任何一个结点的左子树和右子树的高度差的绝对值不大于1;
(2)它的左右子树也都是平衡二叉树
如图就是一个平衡树
平衡二叉树的的构建
对于常规的平衡树的构建,留看看基友的博客,写的清晰明了,懂递归就能看懂,这个是链接 有兴趣的点过去看看
http://northk.wang/2016/01/18/%E6%9E%84%E5%BB%BAAVL%E6%A0%91/
下面我来get一种新的构建方法。根据排序树的特点,左子树数据小于root,右子树都大于root,辣么技能来了,我们先把数据进行排序(用效率最好的排序方法),然后用中间数据作为AVL树的根,小端数据作为左子树,大端数据作为右子树,然后用递归的方式将数据有序列构建成一棵AVL树。
基本思路如下:
(1) 先对数据进行排序得到有序列
(2)将有序列的中间元素作为根结点,小端数据作为左子树,大端数据作为右子树;
(3)根据(2)的方法分别构建树的左右子树;
构建过程如图所示:
代码实现如下:
void Quick_Sort( data, begin,end );//用快排的方式将数据按规定键值排序,在构建树是假设数据已经有序
void Create_AVL_Tree(BiTree root,data,begin,end){
int mind;
if(end>0){
mid=(begin+end)/2;
root= new BiTree;
root->data=data[mid];
root->Lchild=NULL;
root->Rchild=NULL;
Create_AVL_Tree(root->Lchild,data,begin,mid-1);
Create_AVL_Tree(root->Rchild,data,mid+1,end);
}
}
如果给定数据有序,辣么时间复杂度为O(logn);如果是无序列,通过快排后再建树,时间复杂度和一般模式一样都为O(nlogn);
AVL树的插入
比较苦逼,到目前为止还没有想到好的解决方法不使用传统方法插入,而传统的插入根传统AVL树的建立是一样的。所以还是按部就班的来吧。连接在上面,自己点开看吧。
AVL树的删除
对于AVL树的删除,有一种叫懒惰删除,也就是假删除的算法,就是直接在结点上标记结点的死活,这样就不会访问到结点,而树的结构也没改变,是不是很爽啊?但是,这种方法终归是有缺陷的。而对于真正的删除是特别苦逼的,容我研究一下,以后再说吧