对于查找这个操作,相信大家都不陌生
顺序查找 ( Sequential Searching )
最直接的查找便是顺序查找 ( Sequential Searching ),其实就是从头到尾遍历一遍,看有无自己想要的元素,充满暴力,所以同时也意味着效率低下,时间复杂度O(n) ,所以要改进
二分查找 ( Binary Searching )
先决条件,要求序列有序
这是一个二分查找的实现代码:
int Binary_search(int left,int right,int it){
int mid;
while(left<=right){
mid = (right+left)/2;
if(num[mid]>it){
right = mid - 1;
}else if(num[mid]<it){
left = mid + 1;
}else{
return mid;
}
}
return 0;
}
时间复杂度O(logn),确实改进挺大,效率很高
缺点:
(1) 要求序列有序,而时刻保持一个序列有序,并不是一个容易的事
(2)数据结构不好,插入,删除效率都不高
需改进
二分查找树 (Binary Search Tree)
BST
(1)一棵树
(2)含有节点,它的左孩子为比他小的,右孩子为比他大的
通过中序遍历我们可以得到一个有序序列
插入操作,遍历插就好了,不多解释了,效率提高
删除操作
- 叶子结点,直接删除
- 含有一个孩子节点,让孩子节点代替他的位置
含有两个孩子,右孩子顶上来,左孩子作为作为右孩子的左子树,当然也可以反过来,只要符合BST要求就好
效率:
(1)完全二叉树或者大多数节点都为两个孩子:O(logn)
(2)Degenerate( 退化的 ) : O(n)
看了这效率的差别时,我们便会想,如果遇到全都是退化的树,那可咋办,于是我们就要让我们构建的树尽量balance
所以为了解决这问题我们又引入了
AVL Tree
它是很好但并不完美的balance Tree
要求: 一个节点左子树的高度 h(left) 右子树的 h(right)
|h(left) - h(right)|<=1
而对于AVL Tree在插入过程中如何进行调整,是其一直都是一棵AVL Tree,又是一个问题
我在这里总结一下经验:
- 先找到最小不平衡树
- 若为LL或RR型可以直接旋转
- 若为LR型,则先旋转为LL型,再旋转
- 若为RL型,则先旋转为RR型,在旋转