当前位置: 首页 > news >正文

后序线索化二叉树,并找到指定结点前驱,非递归逆序输出

#include<stdio.h>
#include<stdlib.h>
#define elemType char
//线索二叉树结点 
typedef struct ThreadNode{
    elemType data;
    struct ThreadNode *lchild,*rchild;
    int ltag,rtag;//用来判断一个结点是否有线索 
}ThreadNode,*ThreadTree;
//全局变量pre,指向当前结点的前驱
ThreadNode* pre=NULL; 
//初始化一颗二叉树 
bool initTree(ThreadNode** root,elemType data){
    *root=(ThreadNode*)malloc(sizeof(ThreadNode));
    if((*root)==NULL){
        return false;
    }
    (*root)->data=data;
    (*root)->lchild=NULL;
    (*root)->rchild=NULL;
    (*root)->ltag=0;
    (*root)->rtag=0;
    return true;
}
//回收动态开辟的内存 
void destroyTree(ThreadNode* root){
    if(root!=NULL){
        if(root->ltag==0){//确保其左孩子不是线索 
            destroyTree(root->lchild);
        }
        if(root->rtag==0){//确保其右孩子不是线索 
            destroyTree(root->rchild);
        }
        free(root);
    }
}
//给指定结点增添左孩子
bool addLeftNode(ThreadNode* curRoot,elemType data){
    ThreadNode* addNode=(ThreadNode*)malloc(sizeof(ThreadNode));
    if(addNode==NULL){
        return false;
    }
    addNode->data=data;
    addNode->lchild=NULL;
    addNode->rchild=NULL;
    addNode->ltag=0;
    addNode->rtag=0;
    curRoot->lchild=addNode;
    return true;
}
//给指定结点增添右孩子
bool addRightNode(ThreadNode* curRoot,elemType data){
    ThreadNode* addNode=(ThreadNode*)malloc(sizeof(ThreadNode));
    if(addNode==NULL){
        return false;
    }
    addNode->data=data;
    addNode->lchild=NULL;
    addNode->rchild=NULL;
    addNode->ltag=0;
    addNode->rtag=0;
    curRoot->rchild=addNode;
    return true;
}
//后序遍历
void postOrder(ThreadNode* curRoot){
    if(curRoot!=NULL){
        postOrder(curRoot->lchild);
        postOrder(curRoot->rchild);
        printf("%c ",curRoot->data);
    }
}

void visit(ThreadNode* q){
    if(q->lchild==NULL){//左子树为空,建立前驱线索 
        q->lchild=pre;
        q->ltag=1;
    }
    if(pre!=NULL&&pre->rchild==NULL){
        pre->rchild=q;
        pre->rtag=1;
    }
    pre=q;
}
//后序遍历二叉树,一边遍历,一边线索化
void postThread(ThreadTree T){
    if(T!=NULL){
        postThread(T->lchild);//后序遍历左子树 
        postThread(T->rchild);//后序遍历右子树 
        visit(T);//线索化根节点 
    }
}
//后序线索化二叉树T
void createPostThread(ThreadTree T){
    pre=NULL;//pre初始化为NULL 
    if(T!=NULL){//非空二叉树才能线索化 
        postThread(T);//后序线索化二叉树 
        if(pre->rchild==NULL){
            pre->rtag=1;//处理最后一个结点 
        }
    }
}

ThreadNode* lastBefoRoot(ThreadNode* curRoot){
    if(curRoot->rtag==1){//表示右孩子被线索化,没有右孩子 
        return curRoot->lchild;
    }
    else return curRoot->rchild; 
}
//根据后序线索二叉树找到指定结点的前驱结点 
ThreadNode* findBefore(ThreadNode* root){
    if(root!=NULL){
        if(root->ltag==0) return lastBefoRoot(root);
        else return root->lchild;
    }
}
//利用后序线索二叉树,逆序输出,非递归 
void RevPostOrder(ThreadNode* root){
    for(ThreadNode* cur=root;cur!=NULL;cur=findBefore(cur)){
        printf("%c ",cur->data);
    }

int main(){
    ThreadTree root;
    initTree(&root,'A');
    addLeftNode(root,'B');
    addRightNode(root,'C');
    addRightNode(root->lchild,'D');
    addLeftNode(root->rchild,'E');
    printf("没有线索化的后序遍历:\n");
    postOrder(root);
    printf("\n");
    
    createPostThread(root);
    printf("利用后序线索二叉树逆序输出:\n");
    RevPostOrder(root);
    printf("\n");
    destroyTree(root);
    return 0;
}

相关文章:

  • 通义万相 2.1 + 蓝耘算力,AI 视频生成的梦幻组合
  • 机器学习图像标记工具MyVision的使用教程
  • Unity, AssetBundle的一些“隐藏”方法
  • JavaScript基础-递增和递减运算符
  • opentitan riscv
  • 前端知识点---库和包的概念
  • 大白话JavaScript实现一个函数,将字符串中的每个单词首字母大写。
  • 用Deepseek写一个五子棋微信小程序
  • Qwen架构与Llama架构的核心区别
  • moodle 开源的在线学习管理系统(LMS)部署
  • AcWing 600. 仰视奶牛 单调栈模板题
  • Cyber Weekly #46:Manus和QwQ-32B
  • AI壁纸进阶宝典:让创作效率与质量飞速提升的法门
  • win11编译llama_cpp_python cuda128 RTX30/40/50版本
  • Trae:引领未来的 AI 编程新时代
  • nodejs学习——nodejs和npm安装与系统环境变量配置及国内加速
  • HPC超算系列2——新手指南1
  • PyTorch系列教程:Tensor.view() 方法详解
  • 定时器Tim输出比较(output compare)
  • Broken pipe
  • 陕西锦宇建设有限公司网站/百度提交网站的入口地址
  • 吉林建设工程信息网/百度关键词排名优化工具
  • wordpress 下载工具/威海seo优化公司
  • 河北省建设工程综合信息网/优化设计七年级下册数学答案
  • 公众号做电影网站/九易建网站的建站模板
  • 网站先做前台还是后台/免费个人网站注册