zoukankan      html  css  js  c++  java
  • 数据结构(6) -- 构建二叉搜索树

    //BinTree.h
    #ifndef BINTREE_H_
    #define BINTREE_H_
    #define ElemType int
    typedef struct _PNode
    {
        ElemType data;
        _PNode *left;
        _PNode *right;
    }PNode;
    
    class BinTree
    {
    private:
        PNode *root;
    public:
        BinTree();
        ~BinTree();
        PNode* GetRoot();    //获得根节点
        void SetRoot(PNode *p) { root = p; }    //设置根节点
        PNode* Find(ElemType x , PNode *p);        //查找元素x所在位置
        PNode* FindMin(PNode *p);    //查找二叉搜索树的最小值
        PNode* FindMax(PNode *p);    //查找二叉搜索树的最大值
        PNode* Insert(ElemType x, PNode *p);  //构建二叉搜索树,所插入的元素按二叉搜索树排列
        PNode* Delete(ElemType x, PNode *p);  //删除二叉搜索树的元素    
        //遍历二叉树
        void PreOrder(PNode *p);  //先序遍历
        void CenOrder(PNode *p);  //中序遍历
        void Trave(PNode *p);     //层次遍历
    };
    #endif
    
    
    /////////////////////////////////////////////////////////////////////
    //BinTree.cpp
    #include "BinTree.h"
    #include <iostream>
    #include <queue>
    
    BinTree::BinTree()
    {
        root = NULL;
    }
    
    BinTree::~BinTree(){}
    
    PNode* BinTree::GetRoot()
    {
        return root;
    }
    PNode* BinTree::Find(ElemType x, PNode *p)
    {
        /*
        //尾递归实现
        if (p == NULL)
            return NULL;
        if (x > p->data)
            return Find(x, p->right);
        else if (x < p->data)
            return Find(x, p->left);
        else
            return p;*/
        while (p != NULL)
        {
            if (x > p->data)
                p = p->right;
            else if (x < p->data)
                p = p->left;
            else
                return p;
        }
        return NULL;
    }
    
    PNode* BinTree::FindMin(PNode *p)
    {
        //递归查找
        if (p == NULL)
            return NULL;
        else if (p->left == NULL)
            return p;
        else
            return FindMin(p->left);
    }
    
    PNode* BinTree::FindMax(PNode *p)
    {
        if (p != NULL)
            while (p->right != NULL)
                p = p->right;
        return p;
    }
    
    //遍历二叉树
    void BinTree::PreOrder(PNode *p)
    {
        if (p == NULL)
            return;
        std::cout << p->data << " ";
        PreOrder(p->left);
        PreOrder(p->right);
    }
    
    void BinTree::CenOrder(PNode *p)
    {
        if (p == NULL)
            return;
        CenOrder(p->left);
        std::cout << p->data << " ";
        CenOrder(p->right);
    }
    
    PNode* BinTree::Insert(ElemType x, PNode *p)
    {
        if (p == NULL)
        {
            p = new PNode();
            p->data = x;
            p->left = p->right = NULL;
        }
        else
        {
            if (x < p->data)
                p->left = Insert(x, p->left);
            else if (x > p->data)
                p->right = Insert(x, p->right);
        }
        return p;
    }
    
    PNode* BinTree::Delete(ElemType x, PNode *p)
    {
        PNode *tmp;
        if (p == NULL)
            std::cout << "要删除的元素未找到" << std::endl;
        else if (x < p->data)  //查找要删除的节点
            p->left = Delete(x, p->left);
        else if (x > p->data)
            p->right = Delete(x, p->right);
        else
        {
            //删除的元素左右节点都在,删除右子树的最小节点
            if (p->left != NULL && p->right != NULL)
            {
                tmp = FindMin(p->right);  //查找右子树的最小节点
                p->data = tmp->data;          //将右字数的最小值与当前节点的值互换    
                p->right = Delete(p->data, p->right);    //删除右字数最小节点
            }
            else
            {//删除的元素只有左节点,或只有右节点,或是叶子节点
                tmp = p;
                if (p->left == NULL)  //只有右节点,直接用右节点替换要删除节点
                    p = p->right;
                else if(p->right == NULL) //只有左节点,直接用左节点替换要删除节点
                    p = p->left;
                delete tmp;    //如果删除节点是叶子节点,直接删除当前节点
            }        
        }
        return p;
    }
    
    void BinTree::Trave(PNode *p)    //层次遍历
    {
        std::queue<PNode*> q;
        q.push(p);
        while (!q.empty())
        {
            PNode *s = q.front();
            std::cout << s->data << " ";
            if (s->left != NULL)
                q.push(s->left);
            if (s->right != NULL)
                q.push(s->right);
            q.pop();
        }
    }
    
    
    ////////////////////////////////////////////////////////
    //测试
    #include <iostream>
    #include "BinTree.h"
    using namespace std;
    
    int main()
    {
        BinTree bt;
        //构造二分查找树
        bt.SetRoot(bt.Insert(4, bt.GetRoot())); //注意跟新根节点
        bt.SetRoot(bt.Insert(3, bt.GetRoot()));
        bt.SetRoot(bt.Insert(5, bt.GetRoot()));
        bt.SetRoot(bt.Insert(6, bt.GetRoot()));
        bt.SetRoot(bt.Insert(7, bt.GetRoot()));
        bt.SetRoot(bt.Insert(8, bt.GetRoot()));
        cout << "先序遍历: " << endl;
        bt.PreOrder(bt.GetRoot());
        cout << endl;
        cout << "中序遍历: " << endl;
        bt.CenOrder(bt.GetRoot());
        cout << endl;
        cout << "层次遍历:" << endl;
         bt.Trave(bt.GetRoot());
        cout << endl;
        cout << "最小值:" << bt.FindMin(bt.GetRoot())->data << endl;
        cout << "最大值:" << bt.FindMax(bt.GetRoot())->data << endl;
        ///////////////////////////////////////////////////////////////////
        cout << endl << "删除节点 5 " << endl;
        bt.Delete(4, bt.GetRoot());
        cout << "先序遍历: " << endl;
        bt.PreOrder(bt.GetRoot());
        cout << endl;
        cout << "中序遍历: " << endl;
        bt.CenOrder(bt.GetRoot());
        cout << endl;
        cout << "层次遍历:" << endl;
        bt.Trave(bt.GetRoot());
        cout << endl;
        cout << "最小值:" << bt.FindMin(bt.GetRoot())->data << endl;
        cout << "最大值:" << bt.FindMax(bt.GetRoot())->data << endl;
        system("pause");
        return 0;
    }
  • 相关阅读:
    第一章 经济基础知识
    105_实例
    SQL开窗函数
    Docker教程:Docker入门实践
    102_HDFS分布式文件系统
    [转]远程连接出现身份验证错误,要求的函数不受支持
    flutter创建工程指定iOS及Android开发语言
    架构师学习之路:康威定律
    智能识别客户收货地址信息
    深入理解Apache Dubbo与实战 pdf
  • 原文地址:https://www.cnblogs.com/yongssu/p/4398119.html
Copyright © 2011-2022 走看看