先序二叉树的线索化,并找指定结点的先序后继

#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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/72809.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蚂蚁集团转正实习大模型算法岗内推

1.负责以大模型为代表的A转术能力的建设和优化&#xff0c;打造业界领先的A(技术系统&#xff0c;主要职责包括A系统结构设计、RAG 系统开发、大模型凯练数据构建、大模型能力评测、大模型准理效果和效率优化等 2.紧密跟踪、探索大模型方向前沿技术&#xff0c;依托丰富目体系化…

未授权漏洞大赏

ActiveMQ未授权访问漏洞 漏洞描述 Apache ActiveMQ是美国阿帕奇&#xff08;Apache&#xff09;软件基金会所研发的一套开源的消息中间件&#xff0c;它支持Java消息服务、集群、Spring Framework等。 Apache ActiveMQ管理控制台的默认管理用户名和密码分别为admin和admin&am…

Python包结构与 `__init__.py` 详解

1. 什么是 __init__.py&#xff1f; __init__.py 是Python包的标识文件&#xff0c;它告诉Python解释器这个目录应该被视为一个包&#xff08;Package&#xff09;。这个文件可以为空&#xff0c;也可以包含初始化代码。 1.1 基本作用 包的标识 将普通目录转换为Python包允许…

Web前端开发——HTML基础下

HTML语法 一表格1.基本格式2.美化表格合并居中属性 二表单1.input2.select3.textarea4.button5.date6.color7.checkbox8.radio9.range10.number 一表格 1.基本格式 HTML表格由<table>标签定义 其中行由<tr>标签定义&#xff0c;单元格由<td>定义。我们先来…

小程序事件系统 —— 33 事件传参 - data-*自定义数据

事件传参&#xff1a;在触发事件时&#xff0c;将一些数据作为参数传递给事件处理函数的过程&#xff0c;就是事件传参&#xff1b; 在微信小程序中&#xff0c;我们经常会在组件上添加一些自定义数据&#xff0c;然后在事件处理函数中获取这些自定义数据&#xff0c;从而完成…

安卓设备root检测与隐藏手段

安卓设备root检测与隐藏手段 引言 安卓设备的root权限为用户提供了深度的系统控制能力&#xff0c;但也可能带来安全风险。因此&#xff0c;许多应用&#xff08;如银行软件、游戏和流媒体平台&#xff09;会主动检测设备是否被root&#xff0c;并限制其功能。这种对抗催生了ro…

如何在Ubuntu上直接编译Apache Doris

以下是在 Ubuntu 22.04 上直接编译 Apache Doris 的完整流程&#xff0c;综合多个版本和环境的最佳实践&#xff1a; 注意&#xff1a;Ubuntu的数据盘VMware默认是20G&#xff0c;编译不够用&#xff0c;给到50G以上吧 一、环境准备 1. 安装系统依赖 # 基础构建工具链 apt i…

vuejs相关链接和格式化插件推荐

vue官网&#xff1a; https://cn.vuejs.org/ 配合路由设置&#xff1a; https://router.vuejs.org/zh/guide/ element plus (vue3) | element UI (vue2)&#xff1a; https://element-plus.org/zh-CN/#/zh-CN 构建工具vite&#xff1a; https://cn.vitejs.dev/ 右键选择…

IDEA中Git版本回退终极指南:Reset与Revert双方案详解

目录 前言一、版本回退前置知识二、Reset方案&#xff1a;整体改写历史1、IDEA图形化操作&#xff08;推荐&#xff09;1.1、查看提交历史1.2、选择目标版本1.3、选择回退模式1.3.1、Soft&#xff08;推荐&#xff09;1.3.2、Mixed1.3.3、Hard&#xff08;慎用&#xff09;1.3.…

PHP并发请求优化:使用`curl_multi_select()`实现高效的多请求处理

PHP并发请求优化&#xff1a;使用curl_multi_select()实现高效的多请求处理 背景 最近在项目中遇到一个需求&#xff0c;需要从多个 1 级网站&#xff08;超过 200 个&#xff09;获取数据&#xff0c;并且是通过 POST 请求瞬间发送到这些网站上。开始时我直接使用了 curl_ex…

【leetcode hot 100 206】反转链表

解法一&#xff1a;&#xff08;头插法&#xff09;在遍历链表时&#xff0c;将当前节点的 next 指针改为指向前一个节点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val)…

【QT】-易错点笔记-2025-2-7

1,QList<phy_simulator*> pList;为空不能append()追加,要先new,再用 QList<phy_simulator> pList为空时,确实不能调用 append() 方法。原因很简单,QList 是一个类对象,在 C++ 中,指针本身并不代表它指向的对象。因此,当你有一个指向 QList<phy_simulato…

AI-Deepseek + PPT

01--Deepseek提问 首先去Deepseek问一个问题&#xff1a; Deepseek的回答&#xff1a; 在汽车CAN总线通信中&#xff0c;DBC文件里的信号处理&#xff08;如初始值、系数、偏移&#xff09;主要是为了 将原始二进制数据转换为实际物理值&#xff0c;确保不同电子控制单元&…

实验一:在Windows 10/11下配置和管理TCP/IP

目录 1.【实训目标】 2.【实训环境】 3.【实训内容】 4.【实训步骤】 1.【实训目标】 1.了解网络基本配置中包含的协议、服务、客户端。 2.了解Windows支持的网络协议及参数设置方法。 3.掌握TCP/IP协议的配置。 2.【实训环境】 硬件环境&#xff1a;每人一台计算机&a…

Java直通车系列14【Spring MVC】(深入学习 Controller 编写)

目录 基本概念 编写 Controller 的步骤和要点 1. 定义 Controller 类 2. 映射请求 3. 处理请求参数 4. 调用业务逻辑 5. 返回响应 场景示例 1. 简单的 Hello World 示例 2. 处理路径变量和请求参数 3. 处理表单提交 4. 处理 JSON 数据 5. 异常处理 基本概念 Cont…

EA - 开源工程的编译

文章目录 EA - 开源工程的编译概述笔记环境备注x86版本EABase_x86EAAssert_x86EAThread_x86修改 eathread_atomic_standalone_msvc.h原始修改后 EAStdC_x86EASTL_x86EAMain_x86EATest_x86备注备注END EA - 开源工程的编译 概述 EA开源了‘命令与征服’的游戏源码 尝试编译. 首…

一招解决Pytorch GPU版本安装慢的问题

Pytorch是一个流行的深度学习框架&#xff0c;广泛应用于计算机视觉、自然语言处理等领域。安装Pytorch GPU版本可以充分利用GPU的并行计算能力&#xff0c;加速模型的训练和推理过程。接下来&#xff0c;我们将详细介绍如何在Windows操作系统上安装Pytorch GPU版本。 查看是否…

为解决局域网IP、DNS切换的Windows BAT脚本

一、背景 为解决公司普通人员需要切换IP、DNS的情况&#xff0c;于是搞了个windows下的bat脚本&#xff0c;可以对有线网络、无线网络进行切换设置。 脚本内容 echo off title 多网络接口IP切换工具:menu cls echo echo 请选择要配置的网络接口: echo echo 1. 有线网络&am…

uni_app实现下拉刷新

1. 在页面配置中启用下拉刷新 首先&#xff0c;你需要在页面的 pages.json 文件中启用下拉刷新功能。 {"pages": [{"path": "pages/index/index","style": {"navigationBarTitleText": "首页","enablePull…

OpenCV计算摄影学(14)实现对比度保留去色(Contrast Preserving Decolorization)的函数decolor()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将彩色图像转换为灰度图像。它是数字印刷、风格化的黑白照片渲染&#xff0c;以及许多单通道图像处理应用中的基本工具。 cv::decolor 是 OpenCV…