//后序线索,这种方法不容易想到
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>using namespace std;struct TREE{int    val;TREE *ch[2];TREE *thread;//该节点的线索的下一个节点 TREE(){}TREE(int val){this->val = val;ch[0] = ch[1] = NULL;thread = NULL;}
};void buildT(TREE * &T){int x;scanf("%d", &x);if(x == -1) return ;T = new TREE(x);buildT(T->ch[0]);buildT(T->ch[1]);
}void postThread(TREE *T, TREE *pre){if(!T) return;postThread(T->ch[0], T);postThread(T->ch[1], T);if(pre){if(pre->ch[0] == T && pre->ch[1])//T是左子树 T->thread = pre->ch[1]; //T的下一个节点就是它的兄弟节点 else //T是右子树T->thread = pre;//T的下一个节点就是它 的父亲节点             }
}void printT_pre(TREE *T){//前序打印 if(!T) return ;printf("%d ", T->val);printT_pre(T->ch[0]);printT_pre(T->ch[1]);
}void printT_Thread(TREE *T){//后序线索打印 TREE *root = T;bool flag = true;//表明T所在的字数没有访问过 while(1){while(flag && T->ch[0]) T = T->ch[0];printf("%d ", T->val);if(T->thread->ch[0] == T || T->thread->ch[1] == T)flag = false;//如果 T没有兄弟节点了,就一直沿着它的父节点向上走 else flag = true;T = T->thread;if(T == root){//再次回到最顶端父节点时, 结束! printf("%d ", T->val);           break;}}
}int main(){TREE *T = NULL;buildT(T);printT_pre(T);printf("\n");postThread(T, NULL);printT_Thread(T);printf("\n");return 0;
}

下面是基本按照同样的套路实现二叉树的先序,中序,后序的线索

//先序线索
#include<stdio.h>
#include<stdlib.h>
#define Thread 1
#define Tlink 0
typedef struct tree
{int d;struct tree* lchild;struct tree* rchild;int Ltag, Rtag;
}*TREE;void build_tree(TREE &T)
{int d;scanf("%d", &d);if(d!=-1){T=(TREE)malloc(sizeof(tree));T->d=d;T->lchild=T->rchild=NULL;T->Ltag=T->Rtag=Tlink;build_tree(T->lchild);build_tree(T->rchild);}
} TREE pre;void preThread_tree(TREE p)
{if(p){if(!p->lchild){p->lchild=pre;p->Ltag=Thread;}if(!pre->rchild){pre->rchild=p;pre->Rtag=Thread;}pre=p;if(p->Ltag==Tlink)//考虑到只有一个结点或两个节点情况, preThread_tree(p->lchild);//如果没有 if语句可能出现死循环 if(p->Rtag==Tlink)preThread_tree(p->rchild);}
}void print_preThr_tree(TREE T)
{TREE p=T;while(1){ while(p->Ltag==Tlink){printf("%d ", p->d);p=p->lchild;}printf("%d ", p->d);p=p->rchild;if(p==T) break;while(p->Rtag==Thread){printf("%d ", p->d);p=p->rchild;}}
}void print_tree(TREE T)
{if(T){printf("%d ", T->d);print_tree(T->lchild);print_tree(T->rchild);}
}int main()
{TREE T=NULL;build_tree(T);print_tree(T);//递归先序遍历 printf("\n");    pre=T;preThread_tree(T);//非递归先序遍历 pre->rchild=T;print_preThr_tree(T);return 0;
}
//中序线索
#include<stdio.h>
#include<stdlib.h>
#define Thread 1
#define Tlink 0
typedef struct tree
{int d;struct tree* lchild;struct tree* rchild;int Ltag, Rtag;
}*TREE;void build_tree(TREE &T)
{int d;scanf("%d", &d);if(d!=-1){T=(TREE)malloc(sizeof(tree));T->d=d;T->lchild=T->rchild=NULL;T->Ltag=T->Rtag=Tlink;build_tree(T->lchild);build_tree(T->rchild);}
} TREE pre;void inorThread_tree(TREE p)
{if(p){if(p->Ltag==Tlink)//当只有一个结点的时候,要加上这句话 inorThread_tree(p->lchild);if(!p->lchild){p->lchild=pre;p->Ltag=Thread;}if(!pre->rchild){pre->rchild=p;pre->Rtag=Thread;}pre=p;if(p->Rtag==Tlink)inorThread_tree(p->rchild);}
}/*
上述代码可以简化如下,pre的初值为NULL就好  
void inorThread_tree(TREE p)
{if(p){  inorThread_tree(p->lchild);if(!p->lchild){p->lchild=pre;p->Ltag=Thread;}if(pre && !pre->rchild){pre->rchild=p;pre->Rtag=Thread;}pre=p;  inorThread_tree(p->rchild);}
}
*/void print_tree(TREE T){if(T){print_tree(T->lchild);printf("%d ", T->d);print_tree(T->rchild);}
}void print_inorThr_tree(TREE T)
{TREE p=T;while(1){while(p->Ltag==Tlink)p=p->lchild;printf("%d ", p->d);while(p->Rtag==Thread){p=p->rchild;printf("%d ", p->d);}p=p->rchild;if(p==T)break;}
}int main()
{TREE T=NULL;build_tree(T);print_tree(T);//递归中序遍历 printf("\n");    pre=T;inorThread_tree(T);//非递归中序遍历 pre->rchild=T;pre->Rtag=0;//保证只有一个结点的情况 print_inorThr_tree(T);return 0;
}

//后序线索
#include<stdio.h>
#include<stdlib.h>
#define Thread 1
#define Tlink 0
typedef struct tree
{int d;struct tree* lchild;struct tree* rchild;struct tree* rrchild;int Ltag, Rtag;
}*TREE;void build_tree(TREE &T)
{int d;scanf("%d", &d);if(d!=-1){T=(TREE)malloc(sizeof(tree));T->d=d;T->lchild=T->rchild=NULL;T->Ltag=T->Rtag=Tlink;build_tree(T->lchild);build_tree(T->rchild);}
} TREE pre;void postThread_tree(TREE p)
{if(p){if(p->Ltag==Tlink)postThread_tree(p->lchild);if(p->Rtag==Tlink)postThread_tree(p->rchild);if(!p->lchild){p->lchild=pre;p->Ltag=Thread;}if(!pre->rchild ){pre->rchild=p;pre->Rtag=Thread;} else {pre->rrchild=p;}pre=p;}
}void print_postThr_tree(TREE T)
{TREE p=T;while(p->Ltag==Tlink)p=p->lchild;while(1){ printf("%d ", p->d);if(p==T)break; if(p->Rtag == Thread)p=p->rchild;else p=p->rrchild;}
}void print_tree(TREE T)
{if(T){print_tree(T->lchild);print_tree(T->rchild);printf("%d ", T->d);}
}int main()
{TREE T=NULL;build_tree(T);print_tree(T);//递归后序遍历 printf("\n");    pre=T;postThread_tree(T);//非递归后序遍历 pre->rchild=T;pre->Rtag = Thread; print_postThr_tree(T); return 0;
}

先序,中序,后序线索二叉树相关推荐

  1. 二叉树前、中、后线索化及对应前、中、后序线索化遍历

    二叉树前中后线索化及对应前中后序线索化遍历(图解) 二叉树线索化都是套路,会一种另外两种只是稍微修改一下代码 值得一提的是后序线索化输出,逆序思维将后序线索化看成前序,采用"前序线索化输出& ...

  2. python实现二叉树遍历(前序遍历、中序遍历、后序遍历)

    python实现二叉树遍历(前序遍历.中序遍历.后序遍历) 在计算机科学中,二叉树是一种树数据结构,其中每个节点最多有两个子节点,称为左子节点和右子节点.使用集合理论概念的递归定义是(非空)二叉树是元 ...

  3. 二叉树的前序遍历,中序遍历,后序遍历学习 (原)

    经验: 不要死记各个遍历节点的位置,将一个复杂的二叉树当作一个个小的二叉树学习前序遍历,中序遍历,后序遍历会更容易理解 转载于:https://www.cnblogs.com/gyrgyr/p/962 ...

  4. 已知一棵二叉树的中序序列和后序序列,写一个建立该二叉树的二叉链表存储结构的算法...

    已知一棵二叉树的中序序列和后序序列,写一个建立该二叉树的二叉链表存储结构的算法 #define N 10 //二叉树节点的个数 char postorderstr[]={};//后序序列 char i ...

  5. 已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法

    二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或 ...

  6. Python__数据结构与算法——树、二叉树(实现先、中、后序遍历)

    目录 一.树 二.二叉树 树和前面所讲的表.堆栈和队列等这些线性数据结构不同,树不是线性的.在处理较多数据时,使用线性结构较慢,而使用树结构则可以提高处理速度.不过,相对于线性的表.堆栈和队列等线性数 ...

  7. 数据结构与算法之二叉树的先序遍历,中序遍历,后序遍历

    数据结构与算法之二叉树的先序遍历,中序遍历,后移遍历 目录 实现二叉树的先序,中序,后序遍历,包括递归方式和非递归方式 在二叉树中找到一个节点的后继节点 1. 实现二叉树的先序,中序,后序遍历,包括递 ...

  8. C实现二叉树的先序遍历,中序遍历,后序遍历

    1  要创建的二叉树图 2 输出结果图 : 3 完整代码如下: #include<stdio.h> #include<malloc.h>//定义二叉树 typedef stru ...

  9. C/C++二叉树前序遍历,中序遍历,后序遍历

    二叉树的先序遍历,中序遍历,后序遍历 #include <iostream>using namespace std;typedef struct BTNode {char data;str ...

  10. 二叉树的创建、前序遍历、中序遍历、后序遍历

    二叉树的创建.前序遍历.中序遍历.后序遍历 // BTree.cpp : Defines the entry point for the console application. /*  作者:成晓旭 ...

最新文章

  1. 【工具使用系列】关于 MATLAB 机器视觉,你需要知道的事
  2. Js传递数组参数到后台controller的方式
  3. 中间表增加额外字段_如何定制分表中间件
  4. 小bat大装逼(▼へ▼メ)
  5. 注册中心—常见注册中心组件对比分析
  6. mysql 分库分表架构与方案
  7. iPhone X Web 设计
  8. html bootstrap复选框全选,javascript+bootstrap+html实现层级多选框全层全选和多选功能代码实例...
  9. GitHub 标星 14000+,阿里开源的 SEATA 如何应用到极致?
  10. Rwordseg和tmcn安装-2017.09.23
  11. 正在搜索需要的文件一直在搜索_正在被蚕食的百度搜索
  12. python内置函数type_Python基于内置函数type创建新类型
  13. 计算机实验报告word的应用,计算机实验报告模板.doc
  14. 10.第十一章.风险管理
  15. PCB 设计流程(allegro 为例)
  16. 真假马云Deciphering Jack Ma
  17. 如何让机器产生意识之意识具象化
  18. JQuery 基础知识学习(详尽版)
  19. 新AlphaGo首度揭秘:单机运行,4个TPU,算法更强(专访+演讲)
  20. 如果我有一颗私人卫星……|潮科技有奖问答评论精选 ②

热门文章

  1. 安卓自定义Listener
  2. 填充因子-FILL FACTOR
  3. extract和extractValue的差别
  4. 新建网站与新建Asp.Net+Web+应用程序的区别
  5. Hashtable, ArrayList, List, Dictionary学习
  6. Pod详解-生命周期-容器探测
  7. 数据库性能瓶颈的出现
  8. 设计模式在Netty中的应用-观察者模式源码举例
  9. 序列化技术的选型-技术层面
  10. 如何将BeanDefinition注册到IoC容器?