主要是删除操作
二叉排序树的删除
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;
}