线索二叉树构造和遍历

#include <iostream>
using namespace std;

// 定义二叉树节点
struct TreeNode {
    char data; // 节点数据
    TreeNode *left; // 左子树指针
    TreeNode *right; // 右子树指针
    bool ltag; // 左标志,表示左指针是否是指向左子树
    bool rtag; // 右标志,表示右指针是否是指向右子树
};

// 二叉树类
class ThreadedBinaryTree {
private:
    TreeNode *root; // 根节点
    TreeNode *pre; // 先序遍历的前一个节点

    // 创建二叉树(采用了先序创建)
    void createTree(TreeNode *&node) { //参数是结构体指针的引用
        char ch;
        cin >> ch;      //突然发现cin这玩意可以在递归函数调用时记住上一次的读取位置,
                        //继续读取下一个有效字符(很神奇,我之前读取都是一次一次的输入,看上去很呆)
        if (ch == '#') {
            node = nullptr;  
        } else {
            node = new TreeNode{ch, nullptr, nullptr, false, false}; 
            createTree(node->left); //这个参数就很细节,通过直接使用node的左指针来创建左节点,
                                    //避免了该节点指向子节点指针的这步操作
            createTree(node->right);
        }
    }

    // 线索化二叉树(看的很迷)
    void threadTree(TreeNode *node) {
        if (node) {        //该节点存在
            threadTree(node->left);
            if (!node->left) {
                node->ltag = true;
                node->left = pre; 
            }
            if (pre && !pre->right) {
                pre->rtag = true;
                pre->right = node;
            }
            pre = node;
            threadTree(node->right);
        }
    }

    // 遍历线索二叉树
    void inOrder(ThreadedBinaryTree &tree) {
        TreeNode *node = tree.root;
        while (node) {
            while (!node->ltag) {
                node = node->left;
            }
            cout << node->data << " ";
            while (node->rtag) {
                node = node->right;
                cout << node->data << " ";
            }
            node = node->right;
        }
    }

public:
    ThreadedBinaryTree() : root(nullptr), pre(nullptr) {}

    // 创建二叉树
    void create() {
        cout << "输入先序遍历序列(空子树用#表示):";
        createTree(root);
    }

    // 线索化二叉树
    void thread() {
        pre = nullptr;
        threadTree(root);
    }

    // 遍历线索二叉树
    void inOrderTraversal() {
        cout << "线索二叉树的中序遍历:";
        inOrder(*this);
        cout << endl;
    }
};

// 主函数
int main() {
    ThreadedBinaryTree tbt;
    tbt.create(); // 创建二叉树
    tbt.thread(); // 线索化二叉树
    tbt.inOrderTraversal(); // 遍历线索二叉树
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值