动态查找表(二叉排序树)

动态查找表的特点是:表结构在查找过程中动态生成的,即对于给定值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; 
		}
	}
}
    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/shi201619616/article/details/79004804
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞