二叉搜索树的c++实现

一、二叉搜索树的基本概念、难点

前驱:大于该结点关键字的最小关键字的结点

后继:小于该结点关键字的最大关键字的结点

 

删除操作

分为三种情况,都调用了结点替换函数;较复杂的情况为要删除的结点有两个孩子,要进行两次替换,第一次将该结点的右子树中的最小值与该结点的右孩子替换,第二次将该结点与该结点的右子树替换。最后都会调用delete释放内存。

 

二、完整源代码

#include <iostream>

using namespace std;

typedef struct __tree
{
	int data;
	__tree* left;
	__tree* right;
	__tree* parent;
}tree, *pTree;

//打印
void PrintTree(pTree pT);

//查找
pTree Search(pTree pT, int x);
pTree LoopSearch(pTree pT, int x);//查找的循环实现

//最大结点、最小结点
pTree MaxLeaf(pTree root);
pTree MinLeaf(pTree root);

//前驱、后继
pTree TreeSuccessor(pTree pT);
pTree TreePresuccessor(pTree pT);

//插入
void TreeInsert(pTree& pT, int x);

//将u替换为v
void Transplant(pTree& pT, pTree u, pTree v);

//删除结点
void TreeDelete(pTree pT, pTree& z);

int main()
{
	pTree p = NULL;
	int array[9] = {12, 5, 2, 9, 18, 15, 19, 17, 13};
	for (int i = 0; i < 9; ++ i)
		TreeInsert(p, array[i]);
//	cout << Search(p, 19)->data << endl;
// 	cout << TreePresuccessor(p)->data << endl;
// 	cout << TreeSuccessor(p)->data << endl;
// 	cout << MaxLeaf(p)->data << endl;
// 	cout << MinLeaf(p)->data << endl;
//	PrintTree(p);
	pTree pDelete = Search(p, 5); 
	TreeDelete(p, pDelete);
	PrintTree(p);
	return 0;
}

void PrintTree(pTree pT)
{
	if (pT != NULL)
	{
		PrintTree(pT->left);
		PrintTree(pT->right);
		printf("%d\n", pT->data);
	}
}

pTree Search(pTree pT, int x)
{
	if (pT->data == x || pT == NULL)
		return pT;
	if (pT->data > x)
		return Search(pT->left, x);
	else
		return Search(pT->right,x);
}

pTree LoopSearch(pTree pT, int x)
{
	while (pT->data != x && pT != NULL)
		if (pT->data > x)
			pT = pT->left;
		else
			pT = pT->right;
	return pT;
}

pTree MaxLeaf(pTree root)
{
	while (root->right != NULL)
		root = root->right;
	return root;
}

pTree MinLeaf(pTree root)
{
	while (root->left != NULL)
		root = root->left;
	return root;
}

pTree TreeSuccessor(pTree pT)
{
	if (pT->right != NULL)
		return MinLeaf(pT->right);
	pTree pTmp = pT->parent;
	while (pTmp != NULL && pT == pTmp->right)
	{
		pT = pTmp;
		pTmp = pTmp->parent;
	}
	return pTmp;
}

pTree TreePresuccessor(pTree pT)
{
	if (pT->left != NULL)
		return MaxLeaf(pT->left);
	pTree pTmp = pT->parent;
	while (pTmp != NULL && pT == pTmp->left)
	{
		pT = pTmp;
		pTmp = pTmp->parent;
	}
	return pTmp;
}

void TreeInsert(pTree& pT, int x)
{
	pTree pTmp = new tree;
	pTmp->left = pTmp->right = NULL;
	pTmp->data = x;
	pTree pFind = pT;//遍历指针
	pTree pPos = NULL;//要插入的父指针
	while (pFind != NULL)
	{
		pPos = pFind;
		if (pFind->data > x)
			pFind = pFind->left;
		else
			pFind = pFind->right;
	}
	pTmp->parent = pPos;
	if (pT == NULL)
		pT = pTmp;
	else if (pPos->data > x)
		pPos->left = pTmp;
	else
		pPos->right = pTmp;
}

void Transplant(pTree& pT, pTree u, pTree v)
{
	if (u->parent == NULL)
		pT = v;
	else if (u == u->parent->left)
		u->parent->left = v;
	else
		u->parent->right = v;
	if (v != NULL)
		v->parent = u->parent;
}

void TreeDelete(pTree pT, pTree& z)
{
	if (z->left == NULL)
		Transplant(pT, z, z->right);
	else if (z->right == NULL)
		Transplant(pT, z, z->left);
	else
	{
		pTree y = MinLeaf(z->right);
		if (y->parent != z)
		{
			Transplant(pT, y, y->right);
			y->right = z->right;
			y->right->parent = y;
		}
		Transplant(pT, z, y);
		y->left = z->left;
		y->left->parent = y;
	}
	delete z;
	z = NULL;
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值