数据结构-动态查找表(二叉排序树,插入、删除)

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

typedef int ElemType;
typedef struct Node {
	ElemType data;
	struct Node* lchild, * rchild;//左右孩子
}BiTNode;//二叉树结点
typedef struct {
    BiTNode* root;//根节点
    int num;
}BiTree;//二叉树

bool Search_BST(BiTree T, ElemType key, BiTNode*& fa, BiTNode*& p);//由p返回值为key的二叉树结点,fa返回它的父节点
bool Insert_BST(BiTree& T, ElemType key);
void Create_BST(BiTree& T);//建立二叉查找树
void Delete_BST(BiTree& T, ElemType key);

void Create_BST(BiTree& T) {
    cout << "输入结点个数:" << endl;
    int n;  cin >> n;
    if (n <= 0)return;
    T.num = 0; T.root = NULL;//初始化二叉树根节点为空,结点数目为0
    cout << "输入结点关键字值:";
    ElemType e;
    for (int i = 0; i < n; i++) {
        cin >> e;
        Insert_BST(T, e);
    }
}
bool Insert_BST(BiTree& T, ElemType key){
    BiTNode* fa, * p;
    if (Search_BST(T, key, fa, p))//返回父节点和key所在的p结点,若key已经存在与二叉树内,则不用再插入
        return 0;
    else {
        BiTNode* newNode = new BiTNode;//创建新结点
        if (!newNode)exit(0);
        newNode->data = key;
        newNode->rchild = newNode->lchild = NULL;//初始化新结点左右子树为空
        if (!fa)//若未找到key,且返回的父节点为空,则插入的即是父节点
            T.root = newNode;
        else if (fa->data > key)//若插入值较小则放在二叉树左边
            fa->lchild = newNode;
        else
            fa->rchild = newNode;//若插入值较大则放在二叉树右边
        T.num++;
        return true;
    }
}
bool Search_BST(BiTree T, ElemType key, BiTNode*& fa, BiTNode*& p){
    p = T.root; fa = NULL;
    while (p) {
        if (p->data == key)
            return true;
        else if (p->data > key) {
            fa = p;
            p = p->lchild;
        }
        else {
            fa = p;
            p = p->rchild;
        }
    }
    return false;
}
void Delete_BST(BiTree& T, ElemType key) {
    BiTNode* fa, * p;
    Search_BST(T, key, fa, p);
    //T有两棵非空子树。可以选择将该结点元素替换成它的左子树的最大元素或右子树的最小元素
    //(代码中采用的是前者,即用左子树的最大元素替换被删除的节点),然后在删除被替换的元素。
    if (p->lchild && p->rchild) {//若p结点左右子树均存在
        BiTNode* q = p;
        BiTNode* s = p->lchild;
        while (s->rchild) {//找到了s结点,它的值比为p结点小的结点中最大的,它的父节点是q
            q = s;
            s = s->rchild;
        }
        p->data = s->data;//将这个值提上来
        if (q != p)//s即左子树的最大值点,它的父节点q与结点p不是同一结点,
            //也就是说经历了while循环,s是q的右子树,因此s比q大,s的左子树要挂在q的右子树上
            q->rchild = s->lchild;
        else//s即左子树的最大值点,它的父节点q与结点p是同一结点,
            //也就是说只经历了初始化赋值,s是q的左子树,因此s比q小,s的左子树要挂在q的左子树上
            q->lchild = s->lchild;
        delete s;//s的值已经赋给了p,删除s
    }
    else {//若p结点左右子树并非均存在
        //因此找到p结点的唯一子树,q是唯一子树的父节点,即被删除结点
        BiTNode* q = NULL;
        if (!p->lchild) {//左子树不存在,唯一子树就是右子树
            q = p;
            p = p->rchild;
        }
        else{//左子树存在,唯一子树就是左子树
            q = p;
            p = p->lchild;
        }
        if (!fa)//若被删除结点p没有父节点,证明p是根节点,删除根节点后它的唯一子树就是新的根节点
            //(在这个条件分支中被删除的结点左右子树并非均存在)
            T.root = p;
        else {//被删除结点不是根节点
            if (fa->lchild == q)//此时的q是被删除结点,那么接下来就很显然了
                fa->lchild = p;
            else
                fa->rchild = p;
        }
        delete q;
    }
    T.num--;
}
void preorder(BiTNode* p) {
    if (!p)
        return;
    cout << setw(4) << p->data;
    preorder(p->lchild);
    preorder(p->rchild);
}
void Preorder(BiTree T) {
    cout << setw(4) << T.root->data;
    preorder(T.root->lchild);
    preorder(T.root->rchild);
}



int main()
{
    BiTree T;
    Create_BST(T);//建立二叉查找树;
    cout << "\n删除前先序遍历:";
    Preorder(T);//先序遍历
    ElemType key;
    cout << "\n输入要查找的元素的关键字:" << endl;
    cin >> key;
    BiTNode* p, * fa;
    if (Search_BST(T, key, fa, p)) {
        cout << p->data << "找到了!" << endl;
        Delete_BST(T, p->data);
        cout << "删除后先序遍历:";
        Preorder(T);//先序遍历
    }
    else {
        cout << "没找到!" << endl;
    }
    return 0;
}

实验样例

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是二叉排序树的基本操作代码: ```c++ #include<iostream> using namespace std; // 二叉搜索树构体 struct BSTNode { int data; BSTNode *left; BSTNode *right; }; // 查找操作 BSTNode* search(BSTNode *root, int x) { if (root == nullptr || root->data == x) { return root; } else if (x < root->data) { return search(root->left, x); } else { return search(root->right, x); } } // 插入操作 BSTNode* insert(BSTNode *root, int x) { if (root == nullptr) { root = new BSTNode; root->data = x; root->left = nullptr; root->right = nullptr; } else if (x < root->data) { root->left = insert(root->left, x); } else { root->right = insert(root->right, x); } return root; } // 查找最小点 BSTNode* findMin(BSTNode *root) { if (root == nullptr) { return nullptr; } else if (root->left == nullptr) { return root; } else { return findMin(root->left); } } // 删除操作 BSTNode* remove(BSTNode *root, int x) { if (root == nullptr) { return nullptr; } if (x < root->data) { root->left = remove(root->left, x); } else if (x > root->data) { root->right = remove(root->right, x); } else if (root->left != nullptr && root->right != nullptr) { root->data = findMin(root->right)->data; root->right = remove(root->right, root->data); } else { BSTNode *temp = root; if (root->left == nullptr) { root = root->right; } else if (root->right == nullptr) { root = root->left; } delete temp; } return root; } // 中序遍历 void inorder(BSTNode *root) { if (root != nullptr) { inorder(root->left); cout << root->data << " "; inorder(root->right); } } int main() { BSTNode *root = nullptr; root = insert(root, 8); root = insert(root, 3); root = insert(root, 10); root = insert(root, 1); root = insert(root, 6); root = insert(root, 14); root = insert(root, 4); root = insert(root, 7); root = insert(root, 13); inorder(root); // 输出果为:1 3 4 6 7 8 10 13 14 root = remove(root, 6); inorder(root); // 输出果为:1 3 4 7 8 10 13 14 return 0; } ``` 以上代码中,`BSTNode` 是二叉搜索树点的构体,包含数据 `data` 和左右子树指针 `left` 和 `right`。`search` 函数实现查找操作,`insert` 函数实现插入操作,`findMin` 函数查找最小点,`remove` 函数实现删除操作,`inorder` 函数实现中序遍历。最后在 `main` 函数中构建二叉搜索树,并进行插入删除、中序遍历等操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜菜的大鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值