二叉排序树的实现

<pre name="code" class="cpp">#include <iostream>
using namespace std;
typedef int KeyType;
typedef struct BSTNode
{
	KeyType key;
	struct BSTNode* lchild;
	struct BSTNode* rchild;
	struct BSTNode* parent;
}BSTNode,*pBSTNode;


//二叉查找树插入操作
void InsertNode(pBSTNode &root,KeyType key)//插入结点
{
	//可以直接插入(根/左子树/右子树)
	//递归寻找到可以插入的地方(左子树/右子树),二叉查找树不用考虑旋转问题(不需要自平衡)
	if (root==NULL)
	{
		pBSTNode p=(pBSTNode)malloc(sizeof(BSTNode));
		p->key=key;
		p->lchild=NULL;
		p->rchild=NULL;
		p->parent=NULL;
		root=p;
		return;
	}
	if (root->key>key && root->lchild==NULL)
	{
		pBSTNode p=(pBSTNode)malloc(sizeof(BSTNode));
		p->key=key;
		p->lchild=NULL;
		p->rchild=NULL;
		root->lchild=p;
		p->parent=root;
		return;
	}
	if (root->key<key && root->rchild==NULL)
	{
		pBSTNode p=(pBSTNode)malloc(sizeof(BSTNode));
		p->key=key;
		p->lchild=NULL;
		p->rchild=NULL;
		p->parent=root;
		root->rchild=p;
		p->parent=root;
		return;
	}
	//递归寻找插入的位置
	if (root->key>key && root->lchild!=NULL)
	{
		InsertNode(root->lchild,key);
		return;
	}
	else if (root->key<key && root->rchild!=NULL)
	{
		InsertNode(root->rchild,key);
		return;
	}
	else
	{
		return;
	}
}

//二叉查找树查找指定值结点
pBSTNode search(pBSTNode root,KeyType key)
{
	if (root==NULL||root->key==key )//把root=null和root->key=key放在一块(注意先判断是否为NULL)
	{
		return root;
	}
	if (root->key>key)
	{
		search(root->lchild,key);
	}
	else
	{
		search(root->rchild,key);
	}
}

//查找最小关键字
pBSTNode SearchMinNode(pBSTNode root)
{
	if (root==NULL)
	{
		return NULL;//如果空树直接返回NULL
	}
	if (root->lchild==NULL)
	{
		return root;
	}
	else
	{
		return SearchMinNode(root->lchild);//一直找左孩子
	}
}
//查找最大关键字
pBSTNode SearchMaxNode(pBSTNode root)
{
	if (root==NULL)
	{
		return NULL;
	}
	if (root->rchild==NULL)
	{
		return root;
	}
	else
	{
		return SearchMaxNode(root->rchild);//一直找右孩子
	}
}

//查找某结点的前驱
pBSTNode searchPredecessor(pBSTNode p)
{
	//1.有左子树时,找左子树的最大结点(左子树最左边的结点的前继如何寻找?☆)
	//2.无左子树时,向上寻找,直至p结点为其相亲的右子树结点
	if (p==NULL)
	{
		return NULL;
	}
	if (p->lchild)
	{
		return SearchMaxNode(p->lchild);
	}
	else
	{
		if (p->parent==NULL)
		{
			return NULL;
		}
		else
		{
			while (p)
			{
				if (p->parent==NULL)
				{
					return NULL;对最左边的结点的处理
				}
				if (p->parent->rchild==p)
				{
					break;
				}
				p=p->parent;
			}
			return p->parent;
		}
	}
}

pBSTNode searchSuccessor(pBSTNode p)
{
	if (p==NULL)
	{
		return NULL;
	}
	//1.右子树不为空,寻找右子树最小的结点
	//2.右子树为空,向上寻找,找到使p结点成为其父节点的左子树结点
	if (p->rchild)
	{
		return SearchMinNode(p->rchild);
	}
	else
	{
		if (p->parent==NULL)
		{
			return NULL;
		}
		while (p)
		{
			if (p->parent==NULL)
			{
				return NULL;对最右边的结点的处理
			}
			if (p->parent->lchild==p)
			{
				break;
			}
			p=p->parent;
		}
		return p->parent;
	}
}


int DeleteNode(pBSTNode &root,KeyType key)
{
	//首先寻找指定值的结点是否存在
	pBSTNode p=NULL;
	p=search(root,key);
	if (p==NULL)//没有找到,return 0,表示删除失败
	{
		return 0;
	}
	//此时p已经指向要删除的结点
	//1.要删除的结点为叶子结点,既没有左子树,又没有右子树
	if (p->lchild==NULL && p->rchild==NULL)
	{
		//仅有一个结点时,删除后为一棵空树
		if (p->parent==NULL)
		{
			free(p);
			root=NULL;
			return 1;
		}
		else if(p==p->parent->lchild)//删除的是左叶子结点
		{
			p->parent->lchild=NULL;
			free(p);
		}
		else//删除的是右叶子结点
		{
			p->parent->rchild=NULL;
			free(p);
		}
	}
	//2.要删除的结点只有左子树
	else if (p->rchild==NULL)
	{
		//删除的是根结点,重置根节点的值
		if (p==root)
		{
			root=root->lchild;
			free(p);
		}
		//删除的结点是父节点的左子树结点
		else if (p==p->parent->lchild)
		{
			p->parent->lchild=p->lchild;
			p->lchild->parent=p->parent;
			free(p);
		}
		//删除的结点时父节点的右子树结点
		else
		{
			p->parent->rchild=p->lchild;
			p->lchild->parent=p->parent;
			free(p);
		}
	}
	//3.删除的结点只有右子树
	else if (p->lchild==NULL)
	{
		if (p==root)
		{
			root=p->rchild;
			free(p);
		}
		else if (p==p->parent->rchild)
		{
			p->parent->rchild=p->rchild;
			p->rchild->parent=p->parent;
			free(p);
		}
		else
		{
			p->parent->lchild=p->rchild;
			p->rchild->parent=p->parent;
			free(p);
		}
	}
	//4.删除的结点既有左子树又有右子树
	//此时该结点后继结点必无左子树,删除后继结点,后继结点的值替代该结点
	else
	{
		pBSTNode q=NULL;
		q=searchSuccessor(p);
		if (q==NULL)
		{
			return 0;
		}
		KeyType tmp=q->key;
		//free(q);//这里不能直接free(q),因为q可能有右子树,需要递归调用DeleteNode
		DeleteNode(root,tmp);
		p->key=tmp;
	}
	return 1;
}

void Traverse(pBSTNode p)//中序遍历
{
	if (p==NULL)
	{
		return;
	}
	else
	{
		Traverse(p->lchild);
		cout<<p->key<<" ";
		Traverse(p->rchild);
	}
}

int main(int argc,char *argv[])
{
	pBSTNode BST=NULL;
	InsertNode(BST,5);
	for (int i=0;i<10;i++)
	{
		InsertNode(BST,i+1);
	}
	DeleteNode(BST,7);
	Traverse(BST);
}



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值