动态查找表的特点是:表结构在查找过程中动态生成的,即对于给定值key,若表中存在等于key的记录,则查找成功,否则插入关键字key的记录。
1、二叉排序树
(1)、可以是空树
(2)、满足下列条件:若左子树不空,则所有的左子树值小于根节点值。
若右子树不空,则所有的右子树值大于根节点值。
他的左右子树也分别是二叉排序树。
如:这样的一个二叉排序树,A为空格先序遍历:45 12 3 A A 37 24 A A A 53 A 100 61 A 90 78 A A A
int search(bitree T,key k){
if(!T||k==T->data)
return T;
else
if(k<T->data)
return (search(T->lchild,k));
else
return (search(T->rchild,k));
}
二叉排序树是在查找中形成的,每次插入的值必为树的叶子节点。为了找到查找不成功时访问的最后一个节点,需改进到以下算法。
int search(bitree T,key k,bitree f,bitree &p){
//p记录位置
if(!T){
p=f;//f为T的双亲
return false;
}
else
if(k==T->data){
p=T;
return true;
}
else
if(k<T->data){
return search(T->lchild,k,T,p);
}
else{
return search(T->rchild,k,T,p);
}
}
插入算法:
int insert(bitree &T,int e){
if(!search(T,e,NULL,p)){
s=(bitree)malloc(sizeof(bitree));
s->data=e;
s->lchild=NULL;
s->rchild=NULL;
if(!s)T=s;
else
if(e<p->data)p->lchild=s;
else
p->rchild=s;
return true;
}
else
return false;
}
进行删除操作时,有可能会破坏树,所以要修正树:
删除叶子时,不用调整。
删除的结点只有左子树时,直接将左子树向上移动。
删除的结点只有右子树时,直接将右子树当做删除结点的前驱的左子树。
删除的结点有左右子树时,需要找到该节点的左子树a的右子树b的最后一个右子树结点c,将c的值赋给删除结点的值,然后若找到删除结点的左子树有右子树的话,
需将该节点的右子树的前驱的右子树赋值为该节点的左子树。否则,直接将删除结点的左子树上移。
int delete(bitree &T){
if(!p->rchild){
q=p;p=p->lchild;free(q);
}
else
if(!p->lchild){
q=p;
p=p->rchild;
free(q);
}
else{
q=p;s=p->lchild;
while(s->rchild){
q=s;
s=s->rchild;
}
p->data=s->data;
if(p!=q){
q->rchild=s-lchild;
}
else{
q->lchild=s->lchild;
}
}
}