二叉排序树 C++

二叉排序树(Binary Sort Tree),又称二叉查找树。

1、若左子树不为空,则左子树上所有结点的值均小于他的根结构的值;

2、若右子树不为空,则右子树上所有结点的值均大于他的根结构的值;

3、他的左、右子树也分别为二叉排序树。

使用中序遍历时,二叉排序树的输出顺序是由小到大的有序数列。

 

二叉排序树类的: C++ 实现:

#include<iostream>
using namespace std;

template<class T>
struct TreeNode
{
    T element;
    TreeNode<T>*parent, *lnode, *rnode;
    TreeNode(){ parent = lnode = rnode = NULL; }
    TreeNode(const T& key)
    {
        element = key;
        parent = lnode = rnode = NULL;
    }
};

template<class T>
class BStree
{
public:
    BStree() :root(NULL){}
    //获取根结点
    TreeNode<T>* Getroot(){ return root; }
    //中序遍历
    void Inorder(TreeNode<T>*node);                 
    //递归查找
    TreeNode<T>* TreeSearch(TreeNode<T>*node, T key);    
    //迭代查找
    TreeNode<T>* IterativeTreeSearch(TreeNode<T>*node, T key);       
    //插入元素
    void TreeInsert(T key);    
    //最大值
    TreeNode<T>*TreeMax(TreeNode<T>*node);   
    //最小值
    TreeNode<T>*TreeMin(TreeNode<T>*node);   
    //查找前驱结点
    TreeNode<T>*TreePredecessor(T key);    
    //查找后继结点
    TreeNode<T>*TreeSuccessor(T key);            
    //用结点 nodeM 替换结点 nodeN,删除操作的辅助函数
    void TransPlant(TreeNode<T>*nodeM, TreeNode<T>*nodeN);    
    //删除结点是key的元素
    void Delete(T key);                 

private:
    TreeNode<T>* root;
};

//中序遍历
template<class T>
void BStree<T>::Inorder(TreeNode<T>*node)
{
    if (node == NULL)
        return;
    else
    {
        Inorder(node->lnode);
        cout << node->element << " ";
        Inorder(node->rnode);
    }
}

//递归查找,调用时,node的初始值是root
template<class T>
TreeNode<T>* BStree<T>::TreeSearch(TreeNode<T>*node, T key)
{
    if ((node == NULL) || (key == node->element))
    {
        if (node == NULL)
            cout << "不存在该元素" << endl;
        else
            cout << "存在该元素" << endl;
        return node;
    }
        
    if (key > node->element)
         return TreeSearch(node->rnode,key);
    else
        return TreeSearch(node->lnode,key);
}

//迭代查找,node参数为root(根结点)
template<class T>
TreeNode<T>* BStree<T>::IterativeTreeSearch(TreeNode<T>*node, T key)
{
    while (node != NULL&&key != node->element)
    {
        if (key < node->element)
            node = node->lnode;
        else
            node = node->rnode;
    }
    if (node == NULL)
        cout << "不存在该元素" << endl;
    else
        cout << "存在该元素" << endl;
    return node;
}

//插入元素
template<class T>
void BStree<T>::TreeInsert(T key)
{
    TreeNode<T>* y = NULL;
    TreeNode<T>* x = root;
    TreeNode<T>* z = new TreeNode<T>(key);  //将需要插入的元素放入新建立的结点中
    while (x != NULL)  //找到要插入位置的双亲结点
    {
        y = x;
        if (z->element < x->element)
            x = x->lnode;
        else
            x = x->rnode;
    }
    z->parent = y;   
    if (y == NULL)    // 判断要插入的是:左 或 右结点
        root = z;
    else if (z->element>y->element)
        y->rnode = z;
    else
        y->lnode = z;
}

//最大值,一直遍历所给结点的右子树
template<class T>
TreeNode<T>*BStree<T>::TreeMax(TreeNode<T>*node)             
{
    while (node->rnode != NULL)
        node = node->rnode;
    cout << "最大值是:" << node->element << endl;
    return node;
}

// 最小值,一直遍历所给结点的左子树
template<class T>
TreeNode<T>*BStree<T>::TreeMin(TreeNode<T>*node)            
{
    while (node->lnode != NULL)
        node = node->lnode;
    cout << "最小值是:" << node->element << endl;
    return node;
}

//查找后继结点
template<class T>    
TreeNode<T>*BStree<T>::TreeSuccessor(T key)
{
    TreeNode<T>* x = TreeSearch(root, key);    //查找关键字key所对应的结点
    if (x->rnode != NULL)                   //如果结点x存在右结点,则直接查找右结点为跟的最小值
        return TreeMin(x->rnode);
    /*若,不存在右结点
    1、if(x==x->parent->lnode), 则 x 的后继元素即是 x 的双亲结点
    2、if(x==x->parent->rnode),则 x 的双亲 y 及 y->lnode均小于x,
    直到 x 的某一祖先 Yn 为左节点时,Yn 的双亲即是 x 的后继元素
    */
    TreeNode<T>*y = x->parent;
    while (y != NULL&&x == y->rnode)  
    {
        x = y;
        y = y->parent;
    }
    return y;
}

//查找前驱结点
template<class T>   
TreeNode<T>*BStree<T>::TreePredecessor(T key)
{
    TreeNode<T>* x = TreeSearch(root, key);    //查找关键字key所对应的结点
    if (x->lnode != NULL)
        return TreeMax(x->lnode);    //若x的左子树不为空,查找左子树的最大值
    TreeNode<T>*y = x->parent;
    while (y != NULL&&x == y->lnode)
    {
        x = y;
        y = y->lnode;
    }
    return y;
}

//用结点 m 替换结点 n,不包括v的左右子树的更新
template<class T>     
void BStree<T>::TransPlant(TreeNode<T>*nodeM, TreeNode<T>*nodeN)   
{
    if (nodeN->parent == NULL)
        root = nodeM;
    else if (nodeN == nodeN->parent->lnode)   // nodeN 是左结点,更新nodeN->parent 的左结点
        nodeN->parent->lnode = nodeM;
    else
        nodeN->parent->rnode = nodeM;
    if (nodeM != NULL)
        nodeM->parent = nodeN->parent;
}

//删除结点关节字是key的元素
template<class T>     
void BStree<T>::Delete(T key)
{
    TreeNode<T>*z = IterativeTreeSearch(root,key);    //z 是要删除的结点
    if (z->lnode == NULL)
        TransPlant(z->rnode,z);
    else if (z->rnode == NULL)
        TransPlant(z->lnode,z);
    else
    {
        //找要删除结点的后继元素,
        TreeNode<T>*y = TreeMin(z->rnode);   //类的成员函数在调用成员函数(模板)时,直接写函数名,不需要<T>
        if (y->parent != z)
        {
            TransPlant(y->rnode, y);         //用 y 的右结点替代 y
            y->rnode = z->rnode;             //y的右结点 = z的右结点
            y->rnode->parent = y;
        }
        TransPlant(y,z);              //用 y替代z
        y->lnode = z->lnode;
        y->lnode->parent = y;
    }
}

测试代码:注:生成的数组a[20]中,若有重复的数字,会有错误。

#include<iostream>
#include"stdlib.h"
#include<time.h>
#include"BSTreecpp.cpp"
using namespace std;

int main()
{
    //生成要插入的数据
    int max = 500;
    int min = 0;
    srand((unsigned)time(NULL));
    int a[20] = {};
    int x = 0;
    for (int i = 0; i < 20; i++)
    {
        a[i] = rand() % (max - min) + min;
        cout << a[i] << " ";
    }
    cout << "输入数据:" << endl;
    BStree<int>myTree;
    for (int i = 0; i < 20; i++)
        myTree.TreeInsert(a[i]);
    myTree.Inorder(myTree.Getroot());
    cout << "二叉搜索树中序遍历:" << endl;
    //验证递归查找
    int b = 0;
    TreeNode<int>* A = myTree.TreeSearch(myTree.Getroot(), b);
    //验证迭代查找
    TreeNode<int>* B = myTree.IterativeTreeSearch(myTree.Getroot(), a[2]);
    //验证求取最大值
    TreeNode<int>* C = myTree.TreeMax(myTree.Getroot());
    //验证求取最小值
    TreeNode<int>* D = myTree.TreeMin(myTree.Getroot());
    //求取后继结点
    TreeNode<int>*E = myTree.TreeSuccessor(a[1]);
    cout << a[1] << " 的后继元素是:" << E->element << endl;
    //求取前驱结点
    TreeNode<int>*F = myTree.TreePredecessor(a[3]);
    cout << a[3] << " 的前驱元素是:" << F->element << endl;
    //验证删除结点
    myTree.Delete(a[0]);
    myTree.Inorder(myTree.Getroot());
    cout << "二叉搜索树删除元素后:" << endl;
    system("pause");
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/hello-gogo/p/7246236.html

下面是一个简单的二叉排序树C++ 实现: ``` #include <iostream> using namespace std; struct TreeNode { int data; TreeNode* left; TreeNode* right; }; void insert(TreeNode*& node, int data) { if (!node) { node = new TreeNode{ data, nullptr, nullptr }; } else if (data < node->data) { insert(node->left, data); } else if (data > node->data) { insert(node->right, data); } } void inorder(TreeNode* node) { if (node) { inorder(node->left); cout << node->data << " "; inorder(node->right); } } void preorder(TreeNode* node) { if (node) { cout << node->data << " "; preorder(node->left); preorder(node->right); } } void postorder(TreeNode* node) { if (node) { postorder(node->left); postorder(node->right); cout << node->data << " "; } } int main() { TreeNode* root = nullptr; int arr[] = { 5, 3, 7, 1, 9, 4, 6 }; int n = sizeof(arr) / sizeof(arr[0]); for (int i = 0; i < n; i++) { insert(root, arr[i]); } cout << "Inorder traversal: "; inorder(root); cout << endl; cout << "Preorder traversal: "; preorder(root); cout << endl; cout << "Postorder traversal: "; postorder(root); cout << endl; return 0; } ``` 上面的代码实现了二叉排序树的插入和三种遍历方式(中序遍历、先序遍历和后序遍历)。在 `insert` 函数中,如果当前节点为空,就新建一个节点并把数据插入该节点;否则,根据数据大小递归向左或向右子树插入数据。 在 `main` 函数中,创建了一个二叉排序树并插入了一些数据。然后分别对该树进行了三种遍历,并输出结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值