C++二叉搜索树的基本操作

BinarySearchTree.h

#pragma once
struct TreeNode
{
    int key;
    TreeNode* parent;
    TreeNode* leftChild;
    TreeNode* rightChild;
};

class BinarySearchTree
{
private:
    TreeNode* root;
    int NodeNum;                                             //存储节点的个数
public:
    BinarySearchTree();
    BinarySearchTree(int* a, int n);
    ~BinarySearchTree();
    TreeNode* HeadRoot();                                    //返回二叉树根节点
    int TreeNodeNum();                                         //返回二叉树的节点个数
    void InorderTreeWalk()const;                             //递归中序遍历
    void Inorder(TreeNode* n)const;                          
    void InorderTreeWalk1()const;                             //非递归中序遍历
    void PreorderTreeWalk()const;                            //递归先序遍历
    void Preorder(TreeNode* n)const;                         
    void PreorderTreeWalk1()const;                           //非递归先序遍历
    void PostorderTreeWalk()const;                           //递归后序遍历
    void Postorder(TreeNode* n)const;
    void PostorderTreeWalk1()const;                          //非递归后序遍历
    TreeNode* TreeMaximum(TreeNode* n)const;                 //二叉树中值最大的节点
    TreeNode* TreeMinimum(TreeNode* n)const;                 //二叉树中值最小的节点
    void TreeSuccessor()const;                               //后继法实现二叉树的升序排序
    TreeNode* TreeSuccessor(TreeNode* n)const;               //返回节点n的后驱节点
    void TreePredecessor()const;                             //前驱法实现二叉树的降序排序
    TreeNode* TreePredecessor(TreeNode* n)const;             //返回节点n的前继节点
    void TreeInsert(TreeNode* n);                            //插入一个节点
    void TreeInsert(int k);
    void Transplant(TreeNode* u, TreeNode* v);               //用节点v代替节点u成为新的子树,为删除节点做准备
    void TreeDelete(TreeNode* n);                            //删除节点n
    TreeNode* TreeSearch(int k);                             //查找关键字为k的节点
};

BinarySearchTree.cpp

 

#include "BinarySearchTree.h"
#include <iostream>
#include <stack>

BinarySearchTree::BinarySearchTree()
{
    NodeNum = 0;
    root = nullptr;
}

BinarySearchTree::BinarySearchTree(int* a, int n)
{
    root = nullptr;
    NodeNum = 0;
    TreeNode* r;
    for (int i = 0; i < n; ++i)
    {
        TreeNode* t = new TreeNode;
        t->key = *(a + i);
        t->parent = t->leftChild = t->rightChild = nullptr;
        TreeInsert(t);
    }
}

BinarySearchTree::~BinarySearchTree()
{

}

TreeNode* BinarySearchTree::HeadRoot()
{
    return root;
}

int BinarySearchTree::TreeNodeNum()
{
    return NodeNum;
}

void BinarySearchTree::InorderTreeWalk() const
{
    if (!root)
    {
        std::cout << "空树!\n";
        return;
    }
    std::cout << "递归中序遍历:\n";
    Inorder(root);
    std::cout << "\n";
}

void BinarySearchTree::Inorder(TreeNode *n) const
{
    if (n->leftChild)
        Inorder(n->leftChild);
    std::cout << n->key << " ";
    if (n->rightChild)
        Inorder(n->rightChild);
}

void BinarySearchTree::InorderTreeWalk1() const                             //非递归算法都使用栈作为辅助空间来实现
{
    if (!root)
    {
        std::cout << "空树!\n";
        return;
    }
    TreeNode* n = root;
    std::stack<TreeNode*> Stack;
    std::cout << "非递归中序遍历:\n";
    while (n || !Stack.empty())
    {
        while (n)
        {
            Stack.push(n);
            n = n->leftChild;
        }
        n = Stack.top();
        Stack.pop();
        std::cout << n->key << " ";
        n = n->rightChild;
    }
    std::cout << "\n";
}

void BinarySearchTree::PreorderTreeWalk() const
{
    if (!root)
    {
        std::cout << "空树!\n";
        return;
    }
    std::cout << "递归先序遍历:\n";
    Preorder(root);
    std::cout << "\n";
}

void BinarySearchTree::Preorder(TreeNode* n) const
{
    std::cout << n->key << " ";
    if (n->leftChild)
        Preorder(n->leftChild);
    if (n->rightChild)
        Preorder(n->rightChild);
}

void BinarySearchTree::PreorderTreeWalk1() const
{
    if (!root)
    {
        std::cout << "空树!\n";
        return;
    }
    TreeNode* n = root;
    std::stack<TreeNode*> Stack;
    std::cout << "非递归先序遍历:\n";
    while (n || !Stack.empty())
    {
        while (n)
        {
            std::cout << n->key << " ";
            Stack.push(n);
            n = n->leftChild;
        }
        n = Stack.top();
        Stack.pop();
        n = n->rightChild;
    }
    std::cout << "\n";

}

void BinarySearchTree::PostorderTreeWalk() const
{
    if (!root)
    {
        std::cout << "空树!\n";
        return;
    }
    std::cout << "递归后序遍历:\n";
    Postorder(root);
    std::cout << "\n";
}

void BinarySearchTree::Postorder(TreeNode* n) const
{
    if (n->leftChild)
        Postorder(n->leftChild);
    if (n->rightChild)
        Postorder(n->rightChild);
    std::cout << n->key << " ";
}

void BinarySearchTree::PostorderTreeWalk1() const
{
    if (!root)
    {
        std::cout << "空树!\n";
        return;
    }
    TreeNode* n = root;
    std::stack<TreeNode*> Stack;
    int flag[30];                                                                //flag是用来标志入栈节点是否访问过其右子树
    std::cout << "非递归后序遍历:\n";
    while (n)
    {
        Stack.push(n);
        n = n->leftChild;
        flag[Stack.size()] = 0;
    }
    while (!Stack.empty())
    {
        n = Stack.top();
        while (n->rightChild && flag[Stack.size()] == 0)
        {
            flag[Stack.size()] = 1;
            n = n->rightChild;
            while (n)
            {
                Stack.push(n);
                flag[Stack.size()] = 0;
                n = n->leftChild;
            }
            n = Stack.top();
        }
        n = Stack.top();
        Stack.pop();
        std::cout << n->key << " ";
    }
    std::cout << "\n";
}

TreeNode* BinarySearchTree::TreeMinimum(TreeNode* n) const
{
    while (n->leftChild)
        n = n->leftChild;
    return n;
}

TreeNode* BinarySearchTree::TreeMaximum(TreeNode* n) const
{
    while (n->rightChild)
        n = n->rightChild;
    return n;
}

void BinarySearchTree::TreeSuccessor() const
{
    if (!root)
    {
        std::cout << "空树!\n";
        return;
    }
    TreeNode* min = TreeMinimum(root);
    TreeNode* n = min;
    int count = 1;
    std::cout << "后继法升序排序:\n";
    std::cout << min->key << " ";
    while (count!=NodeNum)
    {
        n = TreeSuccessor(n);
        std::cout << n->key << " ";
        count++;
    }
    std::cout << "\n";
}

TreeNode* BinarySearchTree::TreeSuccessor(TreeNode* n) const                     //根据二叉树的性质,找节点n的后继,若n有右孩子的话,后继就是以n->rightChild为根节点子树的最小值
{                                                                                //若n没有右孩子的话,则顺着树往上找,直到遇到这样的节点,这个节点是它的双亲的左孩子
    if (n->rightChild)
        return TreeMinimum(n->rightChild);
    TreeNode* m = n->parent;
    while (m && m->rightChild == n)
    {
        n = m;
        m = n->parent;
    }
    return m;
}

void BinarySearchTree::TreePredecessor() const
{
    if (!root)
    {
        std::cout << "空树!\n";
        return;
    }
    TreeNode* max = TreeMaximum(root);
    TreeNode* n = max;
    int  count = 1;
    std::cout << "前驱法降序排序:\n";
    std::cout << max->key << " ";
    while (count != NodeNum)
    {
        n = TreePredecessor(n);
        std::cout << n->key << " ";
        count++;
    }
    std::cout << "\n";
}

TreeNode* BinarySearchTree::TreePredecessor(TreeNode* n) const                //前驱的话和后继是对称的
{
    if (n->leftChild)
        return TreeMaximum(n->leftChild);
    TreeNode* m = n->parent;
    while (m && m->leftChild == n)
    {
        n = m;
        m = n->parent;
    }
    return m;
}

void BinarySearchTree::TreeInsert(TreeNode* t)
{
    if (!root)
    {
        root = t;
    }
    else
    {
        TreeNode* r;
        r = root;
        while (1)
        {
            if (t->key < r->key)
            {
                if (!r->leftChild)
                {
                    r->leftChild = t;
                    t->parent = r;
                    break;
                }
                else
                    r = r->leftChild;
            }
            else
            {
                if (!r->rightChild)
                {
                    r->rightChild = t;
                    t->parent = r;
                    break;
                }
                else
                    r = r->rightChild;
            }
        }
    }
    NodeNum++;
}

void BinarySearchTree::TreeInsert(int k)
{
    TreeNode* t = new TreeNode;
    t->key = k;
    t->parent = t->leftChild = t->rightChild = nullptr;
    TreeInsert(t);
}

void BinarySearchTree::Transplant(TreeNode* u, TreeNode* v)
{
    if (!u->parent)
        root = v;
    else if (u->parent->leftChild == u)
        u->parent->leftChild = v;
    else
        u->parent->rightChild = v;
    if (v)
        v->parent = u->parent;
}

void BinarySearchTree::TreeDelete(TreeNode* n)                                     //删除一个节点的考虑几种情况,比较复杂
{
    if (!n->leftChild)                                                             //无左孩子有右孩子,直接用右孩子来代替
        Transplant(n, n->rightChild);
    else if (!n->rightChild)                                                       //有左孩子无右孩子,直接用左孩子来代替
        Transplant(n, n->leftChild);
    else                                                                           //既有左孩子又有右孩子,这种情况比较复杂
    {
        TreeNode* y = TreeMinimum(n->rightChild);                                  //找到节点n右孩子的后继
        if (y->parent != n)                                                        //如果后继不是n的右孩子,将后继y的右孩子来代替节点y
        {
            Transplant(y, y->rightChild);
            y->rightChild = n->rightChild;
            y->rightChild->parent = y;
        }
        Transplant(n, y);                                                          //用y来代替n
        y->leftChild = n->leftChild;                                               //注意各节点之间指针parent,leftChild,rightChild的属性,使其形成一棵完整的二叉搜索树
        y->leftChild->parent = y;
    }
    NodeNum--;
    delete n;
}

TreeNode* BinarySearchTree::TreeSearch(int k)
{
    TreeNode* t = root;
    while (t)
    {
        if (k == t->key)
            break;
        else if (k < t->key)
            t = t->leftChild;
        else
            t = t->rightChild;
    }
    return t;
}

 

main.cpp

#include "BinarySearchTree.h"
#include <iostream>
const int SIZE = 10;
void Menu(BinarySearchTree& tree)
{
    using std::cout;
    char c;
    do
    {
        system("cls");
        system("color 3E");
        cout << "------------------------------------------------------\n";
        cout << "------------------------------------------------------\n";
        cout << "                        菜单\n";
        cout << "******************************************************\n";
        cout << "******************************************************\n";
        cout << "                   1--        遍历\n";
        cout << "                   2--        排序\n";
        cout << "                   3--        插入\n";
        cout << "                   4--        删除\n";
        cout << "                   0--        退出\n";
        cout << "                   请输入选择:";;
        std::cin >> c;
        switch (c)
        {
            char n;
        case '1':
            do
            {
                system("cls");
                cout << "*************************************\n";
                cout << "                 遍历\n";
                cout << "-------------------------------------\n";
                cout << "             1--  递归遍历\n";
                cout << "             2--  非递归遍历\n";
                cout << "             0--  返回\n";
                cout << "             请输入选择:";
                std::cin >> n;
                switch (n)
                {
                case '1':
                    system("cls");
                    cout << "           递归遍历\n";
                    cout << "-------------------------------\n";
                    tree.PreorderTreeWalk();
                    tree.InorderTreeWalk();
                    tree.PostorderTreeWalk();
                    system("pause");
                    break;
                case '2':
                    system("cls");
                    cout << "            非递归遍历\n";
                    cout << "---------------------------------\n";
                    tree.PreorderTreeWalk1();
                    tree.InorderTreeWalk1();
                    tree.PostorderTreeWalk1();
                    system("pause");
                    break;
                }
            } while (n != '0');
            break;

        case '2':
            system("cls");
            cout << "                   排序\n";
            cout << "---------------------------------------\n";
            tree.TreeSuccessor();
            tree.TreePredecessor();
            system("pause");
            break;

        case '3':
            system("cls");
            cout << "                   插入\n";
            cout << "---------------------------------------\n";
            cout << "请输入要插入的数值:";
            int k;
            std::cin >> k;
            tree.TreeInsert(k);
            tree.InorderTreeWalk();
            std::cout << "插入成功\n";
            system("pause");
            break;

        case '4':
            system("cls");
            cout << "                   删除\n";
            cout << "---------------------------------------\n";
            tree.InorderTreeWalk();
            cout << "请输入要删除的值:";
            int num;
            std::cin >> num;
            TreeNode* q = tree.TreeSearch(num);
            if (!q)
                cout << "未找到该节点\n";
            else
            {
                tree.TreeDelete(q);
                cout << "删除节点成功\n\n";
                tree.InorderTreeWalk();
            }
            system("pause");
            break;
        }
    } while (c != '0');
}
int main(void)
{
    int a[SIZE] = { 15,6,4,3,8,16,8,1,12,20 };
    BinarySearchTree tree(a, SIZE);
    Menu(tree);
    system("pause");
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值