数据结构(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;
}
原文地址:https://www.cnblogs.com/yongssu/p/4398119.html