学习记录:中序线索二叉树

 

目录

1、问题

2、中序线索二叉树

(1)线索二叉树的数据结构定义

(2)普通二叉树的创建

(3)二叉树线索化

(4)遍历中序线索二叉树

前序和后序持续更新


B站up:tyrantlucifer的视频

1、问题

(1)树是否是一个线性结构?

答案是否定的,线性结构一般具有前驱和后继。我们可以使用线索将二叉树转换成一个类似的线性结构。

(2)什么是线索?

线索其实就是将节点连在一起的指针;如果一个二叉树有n个节点,那么有n-1个指针指向他们,但所有节点一共拥有2n个指针,因此有n+1个指针没有利用。使用这n+1个指针,来指向我们二叉树遍历序列的前驱和后继,线索化之后就形成了线索二叉树。

2、中序线索二叉树

(1)线索二叉树的数据结构定义

typedef struct TreeNode{
    char data;
    struct TreeNode* lchild;
    struct TreeNode* rchild;
    int ltag; //左指针是否为线索化指针标志位,1为线索化,0为非线索化
    int rtag; //左指针是否为线索化指针标志位,1为线索化,0为非线索化
}

(2)普通二叉树的创建

void createTree(TreeNode** T, char* data, int* index){
    char ch;
    ch = data[*index];
    *index += 1;
    if(ch == '#'){
        //空节点
        *T = NULL;
    }
    else{
        //非空节点, 前序创建
        *T = (TreeNode*)malloc(sizeof(TreeNode));
        (*T)->data = ch;
        (*T)->ltag = 0;
        (*T)->rtag = 0;
        //创建左子树,逻辑一致,递归
        createTree(&((*T)->lchild), data, index);
        //创建右子树,逻辑一致
        createTree(&((*T)->rchild), data, index);
    }
}

(3)二叉树线索化

根据以上定义,暂时肤浅的认为线索二叉树与普通二叉树的区别只是将未利用的n+1个指针,指向该节点的前驱和后继。因此中序线索二叉树就是在二叉树中序遍历的过程中,将这n+1个指针线索化。

//递归线索化,但会遗漏最后一个
void inThreadTree(TreeNode* T, TreeNode** pre){
    if(T){
        inThreadTree(T->lchild, pre);
        if(T->lchild == NULL){
            T->ltag =1;
            T->lchild = *pre;
        }
        if(*pre != NULL && (*pre)->rchild == NULL){
            (*pre)->rtag = 1;
            (*pre)->rchild = T;
        }
        *pre = T;
        inTreadTree(T->rchild, pre);
    }
}

//最终线索化二叉树
void getThread(TreeNode* T, TreeNode** pre){
    inThreadTree(T, &pre);
    pre -> rtag = 1;
    pre -> rchild = NULL;
}

(4)遍历中序线索二叉树

找到中序的第一个节点

TreeNode* getFirst(TreeNode* T){
    while(T->ltag == 0){
        T = T->lchild;
    return T;

找到下一个节点的函数

TreeNode* getNext(TreeNode* node){
    if(node->rtag ==1)
        return node->rchild;
    else
        return getFirst(node->rchild);
}

主函数

int main(int argc, char* argv[]) {
    TreeNode* T;
    TreeNode* pre = NULL;
    int index = 0;
    createTree(&T, argv[1], &index);
    
    getThread(T, &pre);
    for (TreeNode* node = getFirst(T); node != NULL; node = getNext(node)) {
        printf("%c ", node -> data);
    }
    printf("\n");
    return 0;
}

前序和后序持续更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值