C语言实现中序线索化二叉树并遍历
2017-11-08 14:26
295 查看
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #define OK 1 #define ERROR 0 using namespace std; enum PointerTag {Link, Thread}; //声明枚举,Link == 0:指针,Thread == 1:线索 typedef char TElemType; typedef int Status; typedef struct BiThrNode { TElemType data; struct BiThrNode *lchild, *rchild; //左右孩子指针 PointerTag LTag, RTag; //左右标志 }BiThrNode, *BiThrTree; BiThrTree pre; //全局变量 Status CreateBiTree(BiThrTree &T) { //以先序次序创建二叉树 char ch; cin >> ch; if (ch == '#') T = NULL; else { T = (BiThrNode *)malloc(sizeof(BiThrNode)); //申请空间 T->data = ch; //结点 T->LTag = Link; //初始化结点,其lchild域全部有左孩子 CreateBiTree(T->lchild); //左孩子 CreateBiTree(T->rchild); //右孩子 } return OK; } /* 所有线索化的实质:将二叉树链表中的空指针改为前驱或后继的线索。 ------------------------------------------------------------- 前驱或后继的信息只有在遍历时才能得到, 因此线索化的过程即为在遍历的过程中修改空指针的过程。 -------------------------------------------------------------- 为了记下遍历过程中访问结点的先后关系, 设一个指针pre始终指向刚刚访问过的结点, 而指针p指向当前访问的结点,则pre指向p的前驱 -------------------------------------------------------------- 中序遍历的操作: 若二叉树为空,则空操作;否则 (1)左子树 (2)根节点 (3)右子树 */ void InThreading(BiThrTree p) { //联想中序遍历 if (p) { InThreading(p->lchild); //左子树线索化 if (!p->lchild) { //寻找前驱线索 p->LTag = Thread; p->lchild = pre; } if (!pre->rchild) { //寻找后继线索 pre->RTag = Thread; pre->rchild = p; } pre = p; //保持pre指向p的前驱 InThreading(p->rchild); //左子树完,进行右子树线索化 } } Status InOrderThreading(BiThrTree &Thrt, BiThrTree T) { //线索化算法 //中序遍历二叉树T,并将其中序线索化,Thrt指向头结点 //仿照线性表的存储结构,在二叉树的线索链表上也添加一个头结点 Thrt = (BiThrTree)malloc(sizeof(BiThrNode)); Thrt->LTag = Link; //建立头结点 Thrt->RTag = Thread; //后继线索 Thrt->rchild = Thrt; //右指针回指 if (!T) Thrt->lchild = Thrt; //若二叉树为空,则左指针回指 else { Thrt->lchild = T; //头结点的左子树指向二叉树T pre = Thrt; //pre指向刚刚访问过的结点 InThreading(T); //中序遍历进行 中序 线索化 pre->rchild = Thrt; //将最后一个线索化 pre->RTag = Thread; Thrt->rchild = pre; } return OK; } Status PrintElement(TElemType e) { //输出函数 cout << e; return OK; } Status InOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e)) { //第二个参数运用了函数指针,调用上一步写的输出函数 //T指向头结点,头结点的左链lchild指向根节点,参见前面的线索化算法 //中序遍历二叉树线索化T的非递归算法,对每个数据元素调用输出函数 BiThrNode *p; p = T->lchild; //p指向根节点 while (p != T) { //空树或遍历结束后,p == T while (p->LTag == Link) p = p->lchild; if (!Visit(p->data)) //访问左子树为空的结点 return ERROR; while (p->RTag == Thread && p->rchild != T) { p = p->rchild; //访问后继结点 Visit(p->data); } p = p->rchild; } return OK; } int main() { BiThrNode *T, *Thre; cout<< "先序创建二叉树" << endl; CreateBiTree(T); //在线索化之前,你的有一颗二叉树,不然怎么线索化 InOrderThreading(Thre, T); //中序遍历二叉树T,并将其中序线索化 InOrderTraverse_Thr(Thre, PrintElement);//以双向线索链表为存储结构式对二叉树进行遍历 return 0; } /* 输入:abc##de#g##f### 输出: 9a28 cbegdfa */
资料参考于清华大学出版的数据结构(C语言版)
另外,如果还没看懂,那就看看这篇博客,图文并茂 http://blog.csdn.net/my_heart_/article/details/52086321
还有,本人水平有限,如果说的有错,请大佬赐教
相关文章推荐
- c语言实现二叉树先序,中序,后序(递归),层次遍历,求叶子节点个数及树的深度,下一篇写非递归的遍历
- C语言非递归实现二叉树的先序、中序、后序、层序遍历
- 二叉树的建立以及先序、中序、后序遍历C语言实现
- 数据结构 二叉树的先序 中序 后序遍历(linux 下c语言实现)
- C语言实现 前序、中序、后序遍历二叉树
- 二叉树前序、中序、后序非递归遍历实现(C语言)
- C语言递归实现二叉树的先序、中序、后序遍历
- 用c语言创建一颗二叉树,用递归方法实现对其进行先序、中序和后序遍历的操作。
- 二叉树前序、中序、后序递归遍历实现(C语言)
- c语言实现二叉树的建立与前序、中序、后序、层序遍历
- 【面试算法系列】已知二叉树的前序和中序遍历重建二叉树 - C语言实现
- 【数据结构】中序线索化二叉树后实现一个迭代器来遍历二叉树
- 二叉树的建树、遍历(先序、中序、后序、层次)(递归和非递归)--Java实现
- 二叉树非递归遍历C语言实现
- c语言实现二叉树的先序遍历,中序遍历,后序遍历
- 二叉树的创建,先序、中序、后序遍历的递归实现以及层序遍历
- 二叉树先序、中序,后序遍历的非递归实现
- C语言之二叉树(包括遍历的实现)
- 二叉树的前序,中序,后续,递归及非递归遍历的python实现
- 二叉树的前序、中序、后序遍历Java实现