线索化和非递归遍历的结合

本文介绍了如何将线索化二叉树与非递归前序遍历算法相结合。首先定义了二叉树节点结构,包括访问标志。接着,通过前序输入构建二叉树,然后进行线索化处理,当节点为空或前后继为空时建立线索。最后,实现了非递归的前序遍历线索化二叉树的方法,根据节点访问状态决定遍历方向。
摘要由CSDN通过智能技术生成

根据线索化二叉树和非递归前序遍历二叉树的算法,对两者进行进行结合

代码设计

线索化二叉树和非递归前序遍历二叉树的算法结合,首先需要建立二叉树:定义二叉树节点,并且构造函数createTree()来建立二叉树,为了方便输入,用前序法进行输入#代表空结点。然后将建立好的二叉树线索化,再对线索化二叉树进行非递归的前序遍历。

代码解析

a.定义二叉树节点,并在里面添加一个bool visit,方便遍历时判断该节点是否被访问过

// 定义二叉树结点
struct TreeNode {
    char val;
    TreeNode* left;
    TreeNode* right;
    bool ltag;
    bool rtag;      // 标志指向线索还是树结构
    bool visit;     // 判断是否被访问过
    TreeNode(char x) : val(x), left(NULL), right(NULL), ltag(false), rtag(false),visit(false) {}
};

b.建立二叉树,通过输入建立二叉树,按照前序输入:如果不输入#,则将不断生成前驱,直到出现#开始生成后继,连续输入两个#则转到上一个没有输入后继的节点继续输入。

// 建立二叉树
TreeNode* createTree() {
    char c;
    cin >> c;
    if (c == '#') {
        return nullptr;
    }
    TreeNode* root = new TreeNode(c);
    root->left = createTree();
    root->right = createTree();
    return root;
}

c.线索化,将建立的二叉树线索化,当结点为空时不会往后进行线索化(直接return),如果前驱/后继为空,则会建立左/右线索。

// 线索化二叉树
void inOrderThreaded(TreeNode* root, TreeNode*& pre) {
    if (root == nullptr) {
        return;
    }
    inOrderThreaded(root->left, pre); // 左子树线索化
    if (root->left == nullptr) // 建立左线索
    {
        root->ltag = true;
        root->left = pre;
    }
    if (pre != nullptr && pre->right == nullptr) // 建立右线索
    {
        pre->rtag = true;
        pre->right = root;
    }
    pre = root; // 要进行右子树线索化前先改变pre为root
    inOrderThreaded(root->right, pre);  // 右子树线索化
}

d.非递归前序遍历线索化二叉树,需要根据该节点是否被访问过来进行输入和下一步转跳(left or right)。如果没被访问过则直接输出,未被访问并且左指针不是线索就访问前驱,否则访问后继。访问后继时,要么不是线索,指向下一个节点,要么是线索,指向线索(父亲或者爷爷,如果是最后一个则指向空,遍历结束)。

// 非递归前序遍历线索化二叉树
void preOrderTraversal(TreeNode* root) {
    while (root) {
        if(root->visit==false)
            cout << root->val << " ";
        if (!root->ltag&&root->visit==false)  // 是指针,且没被visit过
        {
            root->visit=true;
            root = root->left;
        }
        else
            root = root->right;

    }
}

e.实现,最后用main实现功能

int main() {
    // 建立二叉树
    cout << "请输入二叉树的节点数据(#表示空节点):" << endl;
    TreeNode* root = createTree();
    TreeNode* pre = nullptr;
    // 线索化二叉树
    inOrderThreaded(root, pre);
    // 非递归前序遍历线索化二叉树
    preOrderTraversal(root);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值