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

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

}

相关推荐
矿渣渣3 分钟前
YAFFS2 文件系统的 `yaffs_dev` 数据结构详解
数据结构·文件系统·nand flash·yaffs2
LabVIEW开发41 分钟前
LabVIEW中算法开发的系统化解决方案与优化
算法·labview
Phoebe鑫43 分钟前
数据结构每日一题day17(链表)★★★★★
数据结构·链表
chenyuhao20241 小时前
链表面试题7之相交链表
数据结构·算法·链表·面试·c#
Pluchon1 小时前
硅基计划2.0 学习总结 壹 Java初阶
java·开发语言·学习·算法
PassLink_1 小时前
[计算机科学#14]:数据结构
数据结构·计算机科学·计算机发展史
仙人掌_lz1 小时前
理解多智能体深度确定性策略梯度MADDPG算法:基于python从零实现
python·算法·强化学习·策略梯度·rl
wjm0410062 小时前
B树和B+树
数据结构·b树
PXM的算法星球2 小时前
一文了解B+树的删除原理
数据结构·b树
C_Liu_2 小时前
C语言:深入理解指针(3)
c语言·数据结构·算法