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

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

}

相关推荐
总斯霖4 分钟前
题解:士兵排列
数据结构·c++·算法
稳兽龙8 分钟前
P4268 [USACO18FEB] Directory Traversal G
c++·算法·换根dp
平谷一勺1 小时前
go切片定义和初始化
数据结构·golang·数组·切片
我是大咖1 小时前
c语言笔记 一维数组与二维数组
c语言·笔记·算法
誓约酱1 小时前
(每日一题) 力扣 283 移动零
linux·c语言·数据结构·c++·算法·leetcode
Luis Li 的猫猫1 小时前
基于Matlab的人脸识别的二维PCA
开发语言·人工智能·算法·matlab
福鸦2 小时前
C++ STL深度解析:现代编程的瑞士军刀
开发语言·c++·算法·安全·架构
橘子真甜~2 小时前
34.二叉树进阶3(平衡二叉搜索树 - AVL树及其旋转操作图解)
数据结构·c++·二叉搜索树·avl树·平衡搜索树
仟濹2 小时前
【算法 C/C++】一维前缀和
数据结构·c++·算法