线索二叉树的生成及遍历

概念

线索二叉树:按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排序为一个线性序列。在改序列中,除第一个结点外每个结点有且仅有一个直接前驱结点;除最后一个结点外每一个结点有且仅有一个直接后继结点。这些指向直接前驱结点和指向直接后续结点的指针被称为线索(Thread),加了线索的二叉树称为线索二叉树。

百科解释:链接


完整C++代码:

#include <iostream>
using namespace std;

//线索二叉树的链式储存结构 
typedef struct BiThrNode
{
    char ch;    // 数据 
    struct BiThrNode *lChild, *rChild;    // 左右子树 
    bool LTag, RTag;    //左右线索标志 
}BiThrNode, *BiThrTree;

BiThrTree pre;    // 前驱节点,用来生成线索二叉树 

/*
* 创建一个二叉树节点 
* 返回创建的新节点 
*/
BiThrTree CreateBiThrNode(char ch)
{
    BiThrTree newT = new BiThrNode;
    newT->ch = ch;
    newT->lChild = newT->rChild = NULL;
    newT->LTag = newT->RTag = false;
    return newT;
}

/*
* 创建二叉树 
* 根据输入先序创建二叉树, 输入 # 表示为空树 
*/
void CreateBiThrTree(BiThrTree &rootT)
{
    char ch;
    cin >> ch;
    if('#' == ch){
        rootT = NULL;
    }
    else{
        rootT = CreateBiThrNode(ch);
        CreateBiThrTree(rootT->lChild);
        CreateBiThrTree(rootT->rChild);
    }
}

/*
* 二叉树的中序线索化 
* 中序遍历依次改写指针 
*/
void InThreading(BiThrTree rootT)
{
    if(rootT){
        InThreading(rootT->lChild);    //线索化左子树 

        // 改写左线索指针 
        if(rootT->lChild == NULL){
            rootT->LTag = true;
            rootT->lChild = pre;
        }else{
            rootT->LTag = false;
        }

        // 改写右线索指针 
        if(pre->rChild == NULL){
            pre->RTag = true;
            pre->rChild = rootT;
        }else{
            pre->RTag = false;
        }

        pre = rootT;    // 记录前驱节点 
        InThreading(rootT->rChild);    // 线索化右子树 
    }
}

/*
* 二叉树的中序线索化 
* 返回头节点
*/
BiThrTree InOrderThreading(BiThrTree rootT)
{
    BiThrTree firstT = CreateBiThrNode('#');
    firstT->LTag = false;
    firstT->RTag = true;

    if(rootT == NULL){
        firstT->rChild = firstT;    // 树为空,则右线索指向自己 
    }else{
        firstT->lChild = rootT;    // 左线索指向树根节点 

        pre = firstT;
        InThreading(rootT);

        // 最后节点的右线索指针指向头节点 
        pre->rChild = firstT;
        pre->RTag = true;

        firstT->rChild = pre;   // 右线索指向最后访问的节点 
    }

    return firstT;
}

/*
* 中序遍历线索二叉树  
* 重复:输出节点数据,获取后继节点
*/ 
void InOder_Traverse_Thr(BiThrTree firstT)
{
    BiThrTree pT = firstT->lChild;    //获取根节点 
    while(pT != firstT){
        // 沿左孩向子下 
        while(! pT->LTag){
            pT = pT->lChild;
        }

        cout << pT->ch << " ";

        // 沿右线索访问后继节点 
        while(pT->RTag && pT->rChild != firstT){
            pT = pT->rChild;
            cout << pT->ch << " ";
        }
        pT = pT->rChild;    // 转向右子树 
    }
}

int main()
{
    BiThrTree rootT;
    CreateBiThrTree(rootT);
    BiThrTree firstT = InOrderThreading(rootT);
    InOder_Traverse_Thr(firstT);
    return 0;
}

销毁的操作没有写,但对于这个程序,这点内存泄露也没什么影响(^_^)
这里只给出了中序线索化及遍历方法,其它的就不写了(^_^)

参考博文:http://blog.csdn.net/jiajiayouba/article/details/9224403


运行结果

这里写图片描述

这里写图片描述


展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值