很多时候会去忘记,你真正在乎的,是什么、、、
set 就是用BST来维护集合的一个容器,书上根本没讲、、、、
定义:二叉排序树(Binary Sort Tree)又称二叉查找树(Binary Search Tree),亦称二叉搜索树。 它或者是一棵空树;或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二叉排序树。(4)中序遍历二叉排序树,所得的中序序列是一个递增的有序序列。
BST的平均时间复杂度为O(log2n),最坏的情况下,会增加至O(n),在刚开始接触BST的时候,我一直觉得是O(n)了 =。= ,那么问题来了,(挖掘机技术到底哪家强)
怎么去优化呢?我觉得会在以后的二叉平衡树(最坏时间复杂度为 log2n )之类的巴拉巴拉的会讲到、、
建树:(这里仅说明整数序列的建树)对于关键字序列不同,生成的二叉排序树可能不同!(见附 1) 过程:将要插入的与根节点比较,小则归到左子树中,大则归到右子树中,该过程也不难理解的吧,这样经过递归之后,可以建成一个有序的树。代码如下
typedef struct node
{
int key;
struct node *l, *r;
}bst_node;
bool insert(bst_node * &p, int k) // 这里的引用传递到现在才弄懂,也是醉了、、
{
if(p == NULL) // 若原树为空,则将新插入的元素作为根节点
{
p = (bst_node *)malloc(sizeof(bst_node));
p -> key = k;
p -> l = p -> r = NULL;
return true;
}
else if(k == p -> key)
{
return false;
}
else if(k < p -> key)
return insert(p -> l, k);
else
return insert(p -> r, k);
}
bst_node * creat(int a[], int n)
{
int i = 0;
bst_node *bt = NULL;
while(i < n)
{
insert(bt, a[i]);
i ++;
}
return bt;
}
查找:查找的过程,其实更像是二分查找,对于关键字序列不同的树,平均查找长度也不同,时间复杂度为O(log2n).
bst_node * search(bst_node *bt , int k)
{
if(bt == NULL || bt -> key == k)
return bt;
if(k < bt -> key)
return search(bt -> l, k);
else
return search(bt -> r, k);
}
删除:个人感觉删除这里还是比较难理解的,不仅仅是指针的移动,删除之前必须进行查找,要考虑多种情况(见附 2),个人感觉海狮模拟一遍比较好,书上的模拟占了好大的一部分、、、
1、需要删除的节点没有左儿子,那么就把右儿子提上去。
2、需要删除的节点的左儿子没有右儿子,那么就把左儿子提上去。
3、以上两种都不满足,就把左儿子子孙中最大的节点提到需要删除的节点上。
下面摘自书上,感觉写的有点麻烦啊、、、
int delete(bst_node * &bt, int k)
{
if(bt == NULL)
return 0;
else
{
if(k < bt -> key)
return delete(bt -> l, k);
else if(k > bt -> key)
return delete(bt -> r, k);
else
{
delete_(bt);
return 1;
}
}
}
void delete_(bst_node * &p)
{
bst_node * q;
if(p -> r == NULL)
{
q = p;
p = p -> l;
free(q);
}
else if(p -> l == NULL)
{
q = p;
p = p -> r;
free(q);
}
else
delete1(p, p -> l);
}
void delete1(bst_node *p, bst_node * &r)
{
bst_node * q;
if(r -> r == NULL)
delete1(p, r -> r);
else
{
p -> key = r -> key;
q = r;
r = r -> l;
free(q);
}
}
附 :
1、 两个序列分别为{5, 2, 1, 6, 7, 4, 8, 3, 9},{1, 2, 3, 4 ,5 , 6, 7, 8, 9}
如下图:
2、 不同点的删除方法。
如下图: