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

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

}

相关推荐
MicroTech20254 分钟前
MLGO微算法科技发布突破性运动想象脑机接口算法,高精度与低复杂度兼得
科技·算法
cici1587412 分钟前
基于不同算法的数字图像修复Matlab实现
算法·计算机视觉·matlab
Savior`L7 小时前
二分算法及常见用法
数据结构·c++·算法
mmz12078 小时前
前缀和问题(c++)
c++·算法·图论
努力学算法的蒟蒻9 小时前
day27(12.7)——leetcode面试经典150
算法·leetcode·面试
甄心爱学习9 小时前
CSP认证 备考(python)
数据结构·python·算法·动态规划
kyle~10 小时前
排序---常用排序算法汇总
数据结构·算法·排序算法
AndrewHZ10 小时前
【遥感图像入门】DEM数据处理核心算法与Python实操指南
图像处理·python·算法·dem·高程数据·遥感图像·差值算法
CoderYanger10 小时前
动态规划算法-子序列问题(数组中不连续的一段):28.摆动序列
java·算法·leetcode·动态规划·1024程序员节