构建、遍历二叉搜索树BST

创建二叉搜索树
V1.0

#include <iostream>
#include <climits>
#define dataType int
using namespace std;

class bstTree{
private:
    dataType val;
    bstTree* left;
    bstTree* right;
public:
    // 构造函数
    bstTree():val(0), left(nullptr), right(nullptr){} 
    bstTree(dataType& newVal):val(newVal), left(nullptr), right(nullptr){}
    
    // 析构函数
    ~bstTree(){
        delete this->left;
        delete this->right;
    }

    // 节点值获取、设置
    dataType getVal() const{
        return this->val;
    }
    void setVal(dataType newVal){
        this->val = newVal;
    }

    // 左孩子获取、设置
    bstTree* getLeft() const{
        return this->left;
    }
    void setLeft(bstTree*& newLeft){
        this->left = newLeft;
    }

    // 右孩子获取、设置
    bstTree* getRight() const{
        return this->right;
    }
    void setRight(bstTree*& newRight){
        this->right = newRight;
    }
};

void buildBSTree(bstTree*& root){
    cout << "输入一个数组构建BST,以空格分隔,\\n结束" << endl;
    dataType dtmp;
    while(cin >> dtmp){
        bstTree* newNode = new bstTree(dtmp); // 不用delete
        
        if(root == nullptr){ // 如果树还没有构造,直接指向新创建的节点
            root = newNode;
        }else{ // 如果已经构造,那么要去左右子树找到合适的位置
            bstTree* pNode = root;
            while(true){
                if(dtmp <= pNode->getVal()){ // 小于等于当前节点,往左找
                    if(pNode->getLeft() == nullptr){
                        pNode->setLeft(newNode);
                        break;
                    }else{
                        pNode = pNode->getLeft(); 
                    }
                }else{
                    if(pNode->getRight() == nullptr){ // 大于当前节点,往右找
                        pNode->setRight(newNode);
                        break;
                    }else{
                        pNode = pNode->getRight();
                    }
                }
            }
        }
        if(cin.get() == '\n') break;
    }
}

// 中序遍历
void inOrder(bstTree* root){
    if(root == nullptr) return;
    inOrder(root->getLeft());
    cout << root->getVal() << " ";
    inOrder(root->getRight());
}

// 先序遍历
void preOrder(bstTree* root){
    if(root == nullptr) return;  
    cout << root->getVal() << " ";
    preOrder(root->getLeft());
    preOrder(root->getRight());
}

// 后序遍历
void postOrder(bstTree* root){
    if(root == nullptr) return;    
    postOrder(root->getLeft());
    postOrder(root->getRight());
    cout << root->getVal() << " ";
}


int main(){
    bstTree* root = nullptr;
    buildBSTree(root);
    
    cout << endl << "中序遍历:" << endl;
    inOrder(root);
    cout << endl << "先序遍历:" << endl;
    preOrder(root);
    cout << endl << "后序遍历:" << endl;
    postOrder(root);
    cout << endl;
    //PostOrder(root);

    return 0;
}

运行,输入输出如下:

输入一个数组构建BST,以空格分隔,\n结束
4 7 5 1 3 6 2

中序遍历:
1 2 3 4 5 6 7 
先序遍历:
4 1 3 2 7 5 6 
后序遍历:
2 3 1 6 5 7 4 

v2.0
比较简洁的写法

#include <iostream>
#include <climits>
#include <algorithm>
#include <vector>
#define dataType int
using namespace std;


struct bstTree{
    dataType val;
    bstTree* left;
    bstTree* right;
    // 构造函数
    bstTree():val(0), left(nullptr), right(nullptr){} 
    bstTree(dataType& newVal):val(newVal), left(nullptr), right(nullptr){}    
};

// 插入元素方法1:无返回值
// 需要一个parent节点保存父节点
// void insertToBST1(bstTree* root, int val)是root指向调用者,但是在这个函数中
// 是对root指针进行操作,应该要返回root给调用者,让调用者指向root所指向的
void insertToBST1(bstTree*& root, int val){
    if(root == nullptr){
        root = new bstTree(val);
        return;
    }
    bstTree* cur = root;
    bstTree* parent;
    // 遍历二叉树找到插入的位置(处于空,根据父节点的值来决定作为父节点的左、右孩子)
    while(cur){
        parent = cur; // 保存父节点
        if(val < cur->val) cur = cur->left;
        else cur = cur->right;
    }

    if(val < parent->val){
        parent->left = new bstTree(val);
    }else{
        parent->right = new bstTree(val);
    }
    delete cur;
    return;
}

// 插入元素方法1:无返回值, 递归写法
bstTree* parent;
void insertToBST1_1(bstTree* root, int val){
    if(root == nullptr){
        if(val < parent->val){
            parent->left = new bstTree(val);
        }else{
            parent->right = new bstTree(val);
        }
        return;
    }
    parent = root;
    if(val < root->val) insertToBST1_1(root->left, val);
    if(val > root->val) insertToBST1_1(root->right, val);
    return;
}

// 插入元素方法2:有返回值
bstTree* insertToBST2(bstTree* root, int val){
    if(root == nullptr){
        root = new bstTree(val);
    }
    if(val < root->val) root->left = insertToBST2(root->left, val);
    if(val > root->val) root->right = insertToBST2(root->right, val);
    return root;
}

// 中序遍历
void inOrder(bstTree* root){
    if(root == nullptr) return;
    inOrder(root->left);
    cout << root->val << " ";
    inOrder(root->right);
}

// 先序遍历
void preOrder(bstTree* root){
    if(root == nullptr) return;  
    cout << root->val << " ";
    preOrder(root->left);
    preOrder(root->right);
}

// 后序遍历
void postOrder(bstTree* root){
    if(root == nullptr) return;    
    postOrder(root->left);
    postOrder(root->right);
    cout << root->val << " ";
}


// 单个元素插入
void buildBSTree(bstTree*& root){
    cout << "输入一个数组构建BST,以空格分隔,\\n结束" << endl;
    dataType dtmp;
    while(cin >> dtmp){
        
        cout << "insertToBST1(root, dtmp) start..." << endl;
        insertToBST1(root, dtmp);  
        cout << "insertToBST1(root, dtmp) over !!!" << endl; 
        
        /*
        cout << "insertToBST1_1(root, dtmp) start..." << endl;
        if(root == nullptr){
            root = new bstTree(dtmp);
        }else{
            insertToBST1_1(root, dtmp);
        }
        cout << "insertToBST1_1(root, dtmp) over !!!" << endl; */
        

        /*
        cout << "inertToBST2(root, dtmp) start..." << endl;
        root = insertToBST2(root, dtmp);   
        cout << "inertToBST2(root, dtmp) over !!!" << endl; */
         
        if(cin.get() == '\n') break;
    }
}


bstTree* sortArrayToBSTree(vector<int>& nums, int l, int r){
    if(l > r) return nullptr;
    int mid = l + ((r - l) / 2);
    bstTree* root = new bstTree(nums[mid]);
    root->left = sortArrayToBSTree(nums, l, mid - 1);
    root->right = sortArrayToBSTree(nums, mid + 1, r);
    return root;
}


int main(){
    bstTree* root = nullptr;
    //buildBSTree(root); // 输入单个插入,进行构造

    // 从有序数组中构造
    vector<int> nums = {4 ,7 ,5 ,1 ,3 ,6 ,2};
    sort(nums.begin(), nums.end());
    root = sortArrayToBSTree(nums, 0, nums.size() - 1);
    
    cout << endl << "中序遍历:" << endl;
    inOrder(root);
    cout << endl << "先序遍历:" << endl;
    preOrder(root);
    cout << endl << "后序遍历:" << endl;
    postOrder(root);
    
    cout << endl << "====end====" << endl;  
    // 指针root不再指向申请的内存空间(也就是bstTree类对象)
    // 在程序退出时bstTree类对象会调用析构函数
    delete root; 
    root = nullptr;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jasscical

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

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

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

打赏作者

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

抵扣说明:

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

余额充值