构造二叉排序树(BST)+二叉排序树的删除

主要是删除操作

二叉排序树的删除
1. 删除叶结点,直接删除
2. 删除结点p只有左子树或右子树,让其子树替代该结点p即可
3. 删除结点p既有左子树又有右子树,以该结点p为根,查找中序遍历下第一个结点t,使这个结点t替换p结点(val覆盖即可),再递归一次删除这个结点t即可

#include <iostream>
#include <string>
using namespace std;

typedef int ElementType;
typedef struct TreeNode{
	ElementType val;
	TreeNode* left;
	TreeNode* right;
	TreeNode(ElementType x):val(x), left(nullptr), right(nullptr){}			
}*ThreadTree;

void visit(TreeNode* node)
{
	cout << node->val << " ";
}

void inOrder(ThreadTree root)
{
	if( root ){
		inOrder(root->left);
		visit(root);
		inOrder(root->right);
	}
}

//	非递归形式创建、插入BST
//	递归形式虽然较简洁,但若二叉树深度过大
//	递归栈创建过多,其效率就会很低 
bool BST_Insert(ThreadTree& root, int n = 0)
{
	if( n <= 0 )
		return false;
	cout << "Please input " << n << " value to insert BST:\n";
	while( n-- )
	{
		ElementType x; cin >> x;
		ThreadTree t = new TreeNode(x);
		if( root == nullptr ){
			root = t;
			continue;
		}

		ThreadTree p = root, pre;
		while( p ){
			pre = p;
			if( x < p->val )
				p = p->left;
			else if( x > p->val )
				p = p->right;
			else
				break;	
		}
		//	BST不存在相同的值 
		if( p && p->val == x ) continue;
		if( x < pre->val ) 
			pre->left = t;
		else if( x > pre->val ) 
			pre->right = t;
	}
	return true;	
}

TreeNode* findFirst(ThreadTree root)
{
	TreeNode* p = root->right;	//右子树中查找最左下结点 
	while( p->left )
		p = p->left;
	return p;	
}

//	二叉排序树的删除
//	1. 删除叶结点p,直接删除
//	2. 结点p只有左子树或右子树,让子树替代该结点p
//	3. 结点p既有左子树又有右子树,以该结点p为根,查找中序遍历下第一个结点t
//	   使这个结点t替换结点p,再递归删除这个结点t即可
bool Node_Delete(TreeNode*& p, const int& val)
{
	if( !p ) return false;
	if( p->val > val )
		return Node_Delete(p->left,  val);
	else if( p->val < val )
		return Node_Delete(p->right, val);
	else{
		//	查找到要删除的结点p 
		TreeNode* t = p;
		//	以下直接更改p的指向,是因为传入的参数是引用型
		//	引用型是直接对原树的结点(而非拷贝)进行操作
			
		//	叶结点
		if( !p->left && !p->right ){
			p = nullptr;
			delete t;
		}
		//	只有左子树 
		else if( p->left && !p->right ){
			p = p->left;
			delete t;
		}
		//	只有右子树 
		else if( !p->left && p->right ){
			p = p->right;
			delete t;
		}
		//	左、右子树均存在 
		else{
			t = findFirst(p);
			p->val = t->val;
			return Node_Delete(p->right, t->val);  	
		}
	}
	return true; 
}

//	注意这里root需传引用类型,因为可能删除根结点也是可能的 
bool BST_Delete(ThreadTree& root, int val = 0)
{
	cout << "delete value " << val << "\n";
	return Node_Delete(root, val);				
}

int main( )
{
	int n;
	cin >> n;
	//8
	//1 2 8 1 10 1 7 3
	
	//8
	//6 2 8 1 10 4 7 3	
	ThreadTree root = nullptr;
	BST_Insert(root, n);
	inOrder(root); cout << "\n\n";
	
	BST_Delete(root, 2);inOrder(root);
	cout << "\n";
	BST_Delete(root, 8); inOrder(root);
	cout << "\n";	
	BST_Delete(root, 10); inOrder(root); 
	cout << "\n";
	BST_Delete(root, 1); inOrder(root); 
	cout << "\n";

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Love_Irelia97/article/details/82890603