二叉搜索树的插入,搜索,删除

        首先提一句什么是二叉搜索树:对于树中的每个结点P,其左孩子中所有值小于该节点的值,而其右孩子中所有值大于该节点的值。前者称作前驱,后者称作后继。利用这种大小特性可以很方便查找到需要的节点。

        二叉搜索树的插入:插入某一节点,值为v,从根节点作为起始,如果v小于当前节点的值,则记录的当前节点的位置作为父节点,把当前节点指针指向其左节点继续判断;否则,记录当前节点的位置,然后指针指向其右节点。重复上述操作直至指针的值为空。然后对比父节点与新增节点的大小以选择新增节点的左右位置。

typedef struct BinaryTree
{
     int data;
	 struct BinaryTree *lchild;
	 struct BinaryTree *rchild;
};
void Insert(BinaryTree **root,int data)
{
	BinaryTree *p=*root;
	BinaryTree *parent=NULL;
	if(NULL==p)
	{
		p=(BinaryTree*)malloc(sizeof(BinaryTree));
		p->data=data;
		p->lchild=NULL;
		p->rchild=NULL;
		*root=p;
		return;
	}
	while(p!=NULL)
	{
		parent=p;
		if(data<p->data)
			p=p->lchild;
		else
			p=p->rchild;
	}
	p=(BinaryTree*)malloc(sizeof(BinaryTree));
	p->data=data;
	p->lchild=NULL;
	p->rchild=NULL;
	if(data<parent->data)
		parent->lchild=p;
	else
		parent->rchild=p;
}

搜索:

bool Search(BinaryTree *root,int data)
{
	if(root==NULL) return false;
	BinaryTree *p=root;
	while(p!=NULL)
	{
		if(p->data==data) return true;
		else if(data<p->data) p=p->lchild;
		else p=p->rchild;
	}
	return false;
}
        删除操作:删除节点要分2个情况考虑:

       1. P(P为待删除节点指针)有两个子节点:采用子节点替换的方法,A、B任选

           A. 从其所有前驱节点中查找最大的节点(这样做的目的是保证替换后,在其所有前驱节点不能有大于其自身的节点),具体做法是:从P的左孩子开始(包括P的左孩     子)循环遍历右孩子,直到找到第一个右孩子为空的节点,将找到的节点的前驱作为其父节点的后继,把找到的节点替换P节点;

           B. 从其所有后继节点中查找最小的节点(这样做的目的是保证替换后,在其所有后继节点不能有小于其自身的节点),具体做法是:从P的右孩子开始(包括P的右孩       子)循环遍历左孩子,直到找到第一个左孩子为空的节点,将找到的节点的后继作为其父节点的前驱,把找到的节点替换P节点;

        2. P最多有一个子节点:P的左子节点不为空,将P的父节点与P的左子节点相连,删除P;P的右子节点不为空,将P的父节点与P的右子节点相连,删除P;P没有子节点,

            直接删除P即可。若P是根节点则需要处理根节点指针。

void Delete(BinaryTree **root,int data)
{
	
	
	BinaryTree *p=*root;
	BinaryTree *parent=p;
	if(NULL==p) return;
	bool flag=false;
	while(!flag&&p!=NULL)
	{
	    
		if(data==p->data)
			flag=true;//找到节点  
		else if(data<p->data)
		{
			parent=p;
			p=p->lchild;
		}
		else
		{
			parent=p;
			p=p->rchild;
		}
	}
	if(!flag)
	{
		printf("未找到该节点.\n");
		return;
	}
	
	if(p->lchild!=NULL&&p->rchild!=NULL)
	{
		// 左右子节点均存在

		BinaryTree *temp=p->rchild;
		BinaryTree *temp_parent=p;
		while(temp->lchild!=NULL)
		{
			temp_parent=temp;
			temp=temp->lchild;
		}
		temp_parent->lchild=temp->rchild;
		p->data=temp->data;
		free(temp);
	}
	else
	{
		// 最多有一个子节点
		if(p->lchild!=NULL)
		{
			if(parent->lchild==p)
				parent->lchild=p->lchild;
			else if(parent->rchild==p)
				parent->rchild=p->lchild;
			else
			{
				//处理根节点
				*root=p->lchild;
				parent=NULL;
			}
			free(p);
		}
		else if(p->rchild!=NULL)
		{
			if(parent->lchild==p)
				parent->lchild=p->rchild;
			else if(parent->rchild==p)
				parent->rchild=p->rchild;
			else
			{
				*root=p->rchild;
				parent=NULL;
			}
			free(p);
		}
		else
		{
			if(parent->lchild==p)
				parent->lchild=NULL;
			else if(parent->rchild==p)
				parent->rchild=NULL;
			else
			{
				*root=NULL;
				parent=NULL;
			}
			free(p);
		}
	}
}
样例输入:提供一个整型数组用于构建二叉搜索树{10,5,28,3,15,20,13,18,16,19},删除值为15的节点





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值