树(二):线索二叉树(ThreadBiTree) 线索化及其非递归遍历C++

树系列文章:
树(一):二叉树(BiTree) 创建+销毁+前中后层遍历(递归+非递归)C++

树(二):线索二叉树(ThreadBiTree) 线索化及其非递归遍历C++

树(三):二叉排序树(BST) C++实现

树(四):平衡二叉树(AVL) C++实现

树(五):哈夫曼树(HuffmanTree) C++实现


以此二叉树为例进行创建:
在这里插入图片描述
前序法创建节点,输入’#'表示为NULL

用前序创建的话需要输入 :ABD##E##C#G##
前序遍历:ABD##E##C#G##
中序遍历:#D#B#E#A#C#G#
后序遍历: ##D##EB###GCA
层序遍历: ABCDEG

在进行线索二叉树线索化的过程中 直接设置一个全局变量 指针 Prev, 表示指向上一个节点的位置 。

思想:
在线索二叉树中,没有空指针,创建线索二叉树的意义是更好的找到节点的前驱和后继。
整个线索二叉树都基于中序遍历。

#include <iostream>
using namespace std;

/*******************************线索二叉树***************************************/
/*
在线索二叉树中,没有空指针,创建线索二叉树的意义是更好的找到节点的前驱和后继。
整个线索二叉树都基于中序遍历。
*/

/**********************************类申明*****************************************/
struct Node
{
    char val;
    struct Node *left;
    struct Node *right;
    int ltag; //0表示正常左孩子,1表示前缀
    int rtag; //0表示正常右孩子,1表示后缀

    Node(char val) : val(val), left(NULL), right(NULL), ltag(0), rtag(0) {}
};

class ThreadBiTree
{
    Node *_root;
    int _i;
    Node *prev; //prev用来指向前一个节点,它最终会指向最后一个节点

public:
    ThreadBiTree(const char *s);    //前序创建, 线索二叉树由于没有空指针,所以无法进行后序销毁
    void inTraverse_setTag(Node *); //中序遍历设置tag
    void inTraverse_byTag(Node *);  //通过tag进行测试

    void inTraverse(Node *); //中序遍历测试程序,测试inTraverse_setTag有没有设置正确
    Node *getRoot() const { return _root; }

private:
    Node *createThreadBiTree(const char *s); //前序创建二叉树
};

/*******************************类成员定义***************************************/
ThreadBiTree::ThreadBiTree(const char *s)
{
    _i = 0;
    _root = createThreadBiTree(s);
    prev = new Node(-1); //头节点
    cout << "ThreadBiTree()" << endl;
}

Node *ThreadBiTree::createThreadBiTree(const char *s)
{
    if ('\0' == s[_i])
        return NULL;
    else if ('#' == s[_i])
    {
        _i++;
        return NULL;
    }
    else
    {
        Node *node = new Node(s[_i]);
        _i++;
        node->left = createThreadBiTree(s);
        node->right = createThreadBiTree(s);
        return node;
    }
}

void ThreadBiTree::inTraverse_setTag(Node *p)
{
    if (p)
    {

        inTraverse_setTag(p->left);

        if (!p->left)
        {
            p->ltag = 1;
            p->left = prev;
        }

        if (!prev->right)
        {
            prev->rtag = 1;
            prev->right = p;
        }
        prev = p;

        inTraverse_setTag(p->right);
    }
}

void ThreadBiTree::inTraverse(Node *node)
{
    if (node)
    {
        if (!node->ltag)
            inTraverse(node->left);
        cout << node->val;
        if (!node->rtag)
            inTraverse(node->right);
    }
}

void ThreadBiTree::inTraverse_byTag(Node *node)
{
    Node *p = node;

    while (p != prev)
    {
        //向左
        while (0 == p->ltag)
        {
            p = p->left;
        }
        cout << p->val;
        //向右
        while (1 == p->rtag)
        {
            p = p->right;
            cout << p->val;
        }
        p = p->right;
    }
    cout << prev->val;
}

/*****************************测试函数**********************************/
int main()
{
    ThreadBiTree tree("ABD##E##C#G##");
    tree.inTraverse_setTag(tree.getRoot());
    // tree.inTraverse(tree.getRoot());
    tree.inTraverse_byTag(tree.getRoot());
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我了解了您的问题。的中序线索化是将中的空指针域改为指向该节点在中序遍历中的前驱或后继节点,从而形成一个线索二叉树。这样做的好处是可以在不使用递归和栈的情况下,高效地遍历。 下面是中序线索化及其非栈非递归遍历的课程设计大纲: 一、课程设计目的和要求 1. 掌握的中序线索化算法; 2. 熟悉非栈非递归遍历的方法; 3. 能够设计实现具有中序线索化功能的,并进行非栈非递归遍历; 4. 能够分析算法时间复杂度,并进行性能测试。 、课程设计内容 1. 算法原理:介绍的中序线索化算法,讲解线索化的实现方法及其原理; 2. 算法设计:设计实现具有中序线索化功能的,并实现非栈非递归遍历; 3. 算法优化:对于非栈非递归遍历算法进行优化,提高算法效率; 4. 算法分析:分析算法时间复杂度,并进行性能测试。 三、课程设计步骤 1. 确定程序设计语言和开发环境; 2. 设计的数据结构,包括节点结构体和结构体; 3. 实现的中序线索化算法; 4. 实现非栈非递归遍历算法; 5. 对非栈非递归遍历算法进行优化; 6. 进行算法时间复杂度分析,并进行性能测试。 四、课程设计参考资料 1. 《数据结构与算法分析》(第三版),作者:Mark Allen Weiss; 2. 《算法基础与应用》(第版),作者:姚期智; 3. 《算法设计与分析基础》(第三版),作者:王晓东等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值