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

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

}

相关推荐
liliangcsdn42 分钟前
探索和学习信任区域策略优化算法-TRPO
学习·算法
无限进步_2 小时前
面试题 02.04. 分割链表 - 题解与详细分析
c语言·开发语言·数据结构·git·链表·github·visual studio
Mr YiRan6 小时前
C++面向对象继承与操作符重载
开发语言·c++·算法
蚊子码农10 小时前
算法题解记录--239滑动窗口最大值
数据结构·算法
liliangcsdn10 小时前
A3C算法从目标函数到梯度策略的探索
算法
陈天伟教授10 小时前
人工智能应用- 材料微观:06.GAN 三维重构
人工智能·神经网络·算法·机器学习·重构·推荐算法
liliangcsdn11 小时前
A3C强化学习算法的探索和学习
算法
Figo_Cheung11 小时前
Figo《量子几何学:从希尔伯特空间到全息时空的统一理论体系》(二)
算法·机器学习·几何学·量子计算
额,不知道写啥。12 小时前
HAO的线段树(中(上))
数据结构·c++·算法
LYS_061812 小时前
C++学习(5)(函数 指针 引用)
java·c++·算法