天天看点

二叉查找树相关操作实现二叉查找树相关操作实现

二叉查找树相关操作实现

#include<cstdio>
#include<cstdlib>

typedef struct BTNode
{
	int data;
	struct BTNode *lchild,*rchild;
}BTNode;

typedef struct BTree
{
	BTNode *root;
}BTree;

int Search(BTNode* T,int key,BTNode *F,BTNode** P)//指针P指向查找路径上最后一个节点
{
	if(!T)
	{
		*P=F;
		return 0;//查找不成功
	}
	else if(key==T->data)
	{
		*P=T;
		return 1;//查找成功
	}
	else if(key<T->data)
		return Search(T->lchild,key,T,P);
	else
		return Search(T->rchild,key,T,P);
}

int Insert(BTNode **T,int key)
{
	BTNode *P,*S;
	if(!Search(*T,key,NULL,&P))
	{
		S=(BTNode *)malloc(sizeof(BTNode));
		S->data=key;
		S->lchild=S->rchild=NULL;
		if(!P)
			*T=S;//为新的根节点
		else if(key<P->data)
			P->lchild=S;
		else
			P->rchild=S;
		return 1;
	}
	else
		return 0;
}

void CTree(BTNode **T,int A[],int n)
{
	int i;
	for(i=0;i<n;i++)
		Insert(T,A[i]);
}

int DeleNode(BTNode **T);

int Delete(BTNode **T,int key)
{
	if(!*T)
		return 0;
	else
	{
		if(key==(*T)->data)
			return DeleNode(T);
		else if(key<(*T)->data)
			return Delete(&(*T)->lchild,key);
		else
			return Delete(&(*T)->rchild,key);
	}
}

/*
二叉选择树节点删除的思想:
1,若删除的为叶子节点,则对树的结构无影响
2,若删除节点只有左子树或者右子树,则将左子树或者
右子树整体上移即可
3,若删除节点P既有左子树又有右子树,则需要
找到待删除节点的直接前驱或者直接后继S来替换P,
然后删除S
*/
int DeleNode(BTNode **T)
{
	BTNode *Q,*S;
	if((*T)->rchild==NULL)//只有左子树
	{
		Q=(*T);
		*T=(*T)->lchild;
		free(Q);
	}
	else if((*T)->lchild==NULL)//只有右子树
	{
		Q=*T;
		*T=(*T)->rchild;
		free(Q);
	}
	else//左右子树都有
	{
		Q=*T;
		S=(*T)->lchild;
		while(S->rchild)
		{
			Q=S;
			S=S->rchild;
		}
		(*T)->data=S->data;
		if(Q!=(*T))
			Q->rchild=S->lchild;//重接Q的右子树
		else
			Q->lchild=S->lchild;//重接Q的左子树
		free(S);
	}
	return 1;
}

void OutPut(BTNode *T)
{
	if(T)
	{
		OutPut(T->lchild);
		printf("%4d",T->data);
		OutPut(T->rchild);
	}
}

int main(int argc,char *argv[])
{
	int Array[10]={62,88,57,48,35,73,51,99,37,93};
	BTree T;
	CTree(&(T.root),Array,10);
	OutPut(T.root);
	Delete(&(T.root),73);
       OutPut(T.root);

	return 0;
}
           

继续阅读