中序线索二叉树
1.创建二叉树
层次遍历创建数组,顺序存储结构转为链式存储结构
2.线索化该二叉树
3.加上头结点
4.线索化遍历二叉树
线索二叉树的链式存储结构如下图:
线索化规则:
线索化二叉树方法:
采用递归方法线索化二叉树,注意点在于线索化二叉树是将该二叉树转换为双向链表
对于其中一个结点的线索化操作为:(pre为当前节点T的前驱节点)
第一步:条件判断让T指向pre,或pre指向T,形成双向链表.
第二步:加入头节点:如下图的四个步骤,添加序号为1,2,4的三条指向。
线索遍历:
下图为线索遍历函数的步骤:
完整代码:
#include<iostream> #include<string> #include<algorithm> using namespace std; //由于前驱和后继信息只有在遍历该二叉树时才能得到,线索化的过程就是在遍历的过程中修改空指针的过程。 char BT[] = "ABCD#EF"; int n = strlen(BT); typedef struct TNode { char data; TNode *lchild, *rchild; int lflag; int rflag; TNode(char d):data(d),lchild(NULL),rchild(NULL){}//构造函数 TNode(){} }; TNode *pre;//定义全局遍历pre 一直指向前驱 void Create(TNode **t, int k) { if (k>n || BT[k - 1] == '#') { *t = NULL; } else { *t = new TNode(BT[k - 1]); Create(&(*t)->lchild, 2 * k); Create(&(*t)->rchild, 2 * k + 1); } }//构造二叉树方式:节点为i,则左子树为2*i,右子树为2*i+1 //中序线索化二叉树 void InThread(TNode *T) { if (T) { InThread(T->lchild); if (!T->lchild) { T->lflag = 1; T->lchild = pre; }//左孩子为空 else { T->lflag = 0; } if (!pre->rchild) { pre->rflag = 1; pre->rchild = T; }//右孩子为空 else { pre->rflag = 0; } pre = T; InThread(T->rchild); } }//两个节点 一个为前驱pre 一个为当 T //中序线索化加上头结点 void CreatThread(TNode *h,TNode *t) { h->lflag = 0; h->rflag = 1; h->rchild = h;//初始化头结点 if (t) { pre = h; h->lflag = 0; h->lchild = t; //第一步 InThread(t); //找到最后一个结点,最后一个结点的值已经赋给pre pre->rchild = h; //第四步 pre->rflag = 1; h->rchild = pre; //第二步 }//其中第三步在inthread函数中执行过了 else {//如果t为空 h->lflag = 1; h->lchild =h; } } void visit(TNode *t) { TNode *p = t; TNode *qian = t->lchild; TNode *hou = t->rchild; cout << "当前节点:"<<p->data; cout << "前驱节点:" << qian->data ; cout << "后继节点:" << hou->data ; cout << "\n"; } void ThreadOrder(TNode *h) { TNode * p; p = h->lchild; //p指向根结点 while (p != h) { while (p->lflag == 0) { p = p->lchild; } visit(p); while (p->rflag == 1 && p->rchild != h) { p = p->rchild; visit(p); } p = p->rchild; } } int main() { TNode *t; TNode *h = new TNode(); Create(&t,1); CreatThread(h,t); cout << "线索遍历二叉树\n"; ThreadOrder(h); }