当前位置: 首页 > 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 preOrder(ThreadNode* curRoot){
    if(curRoot!=NULL){
        printf("%c ",curRoot->data);
        preOrder(curRoot->lchild);
        preOrder(curRoot->rchild);
    }
}
void visit(ThreadNode* p){
    if(p->lchild==NULL){
        p->lchild=pre;
        p->ltag=1;
    }
    if(pre!=NULL&&pre->rchild==NULL){
        pre->rchild=p;
        pre->rtag=1;
    }
    pre=p;
}
//先序遍历二叉树,一边遍历一边线索化
void preThread(ThreadTree T){
    if(T!=NULL){
        visit(T);//先处理根节点 
        if(T->ltag==0){//确保lchild不是前驱线索,避免出现死循环 
            preThread(T->lchild);
        }
        if(T->rtag==0){
            preThread(T->rchild);            
        }

    }

//先序线索化二叉树
void createPreThread(ThreadTree T){
    pre=NULL;//pre初始化为NULL 
    if(T!=NULL){//非空二叉树才能线索化 
        preThread(T);//先序线索化二叉树 
        if(pre->rchild==NULL){
            pre->rtag=1;//处理遍历最后一个结点 
        }
    }
    
}
//-----------------------------------------在先序线索二叉树中找到指定结点p的先序后继next----------------------------------------
ThreadNode* firstAfterRoot(ThreadNode* p){
    if(p!=NULL){
        if(p->ltag==1){//表明左指针被线索化,没有左子树 
            return p->rchild;
        }
        else{
            return p->lchild;
        }
    }
}
ThreadNode* findPreNext(ThreadNode* p){
    if(p!=NULL){
        if(p->rtag==0) return firstAfterRoot(p);
        else return p->rchild;
    }
}
//-----------------------------------------在先序线索二叉树中找到指定结点p的先序后继next----------------------------------------

//利用先序线索二叉树实现非递归先序遍历
void PreOrder(ThreadNode* root){
    for(ThreadNode* cur=root;cur!=NULL;cur=findPreNext(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");
    preOrder(root);
    printf("\n");
    
    createPreThread(root);
    printf("非递归的先序遍历:\n");
    PreOrder(root);
    printf("\n");
    destroyTree(root);
    return 0;
}

相关文章:

  • 1-1 驱动开发HelloWorld
  • 【定制开发】碰一碰发视频系统定制开发,支持OEM
  • 【Java】认识String类、字符串不可变性 + StringBuilder和StringBuffer —— 有码有图有真相
  • Java多线程与高并发专题——关于CopyOnWrite 容器特点
  • Cursor 使用经验,一个需求开发全流程
  • Spring为什么要用三级缓存解决循环依赖?
  • Django模板语法及静态文件
  • 阿里云CTF2025 ---Web
  • Javascript 基础数据类型
  • AI多模态教程:DeepSeek多模态模型解析及实践指南
  • python re正则表达式
  • 分布式锁—7.Curator的分布式锁二
  • 前端知识点---前端里的接口
  • dp_走方格(包含dfs分析,记忆化搜索)
  • 数据结构第六节:二叉搜索树(BST)的基本操作与实现
  • 深入解析 BitBake 日志机制:任务调度、日志记录与调试方法
  • 达梦数据库在Linux,信创云 安装,备份,还原
  • 在Vue中,onLoad,onShow ,mounted的区别
  • go并发学习笔记
  • Java 大视界 -- 基于 Java 的大数据实时数据处理框架性能评测与选型建议(121)
  • 介绍网站ppt该怎么做/最好的搜索引擎
  • 东莞网页制作报价/重庆网站关键词排名优化
  • 企业建设网站意义/阿里指数
  • 铜陵市建设工程管理局网站/搜索引擎营销流程是什么?
  • 五星级酒店网站建设方案/宣传网页制作
  • 网站建设平台网站设计/衡阳seo优化首选