数据结构之线索二叉树(整理严蔚敏数据结构)

来源:互联网 发布:淘宝名龙堂电脑怎么样 编辑:程序博客网 时间:2024/06/06 01:07

线索二叉树可以这样理解:
   1.   PreCreate(): 对于线索二叉树的先序创建过程和一般二叉树的先序创建没有区别(都是建立结点,然后结点赋值)

   2.InThread():中序线索化的过程就是在1.中创建的基础上贴上标签(即给Tag赋值)和给所有的空指针域赋值(中序顺序串起来).

   3.InOrderThread():函数只是用来在2的基础上串上头结点以及对中序遍历的最后一个结点和头结点进行很好的契合.

   4.以上三个函数的契合才是完成一个真正意义上的线索二叉树的创建.



#include<iostream>using namespace std;typedef char ElemType;typedef enum { Link, Thread }PointType;typedef struct BThrNode{ElemType data;struct BThrNode *pLchild, *pRchild;PointType LTag, RTag;}BThrNode, *pBThrNode;void PreCreate(pBThrNode &pT){ElemType c;cin >> c;if (c == '#')pT = NULL;else{pT = new BThrNode;pT->data = c;PreCreate(pT->pLchild);PreCreate(pT->pRchild);}}pBThrNode pRe;//全局变量void InThread(pBThrNode pCur)//中序递归线索化{if (pCur){InThread(pCur->pLchild);//左子树线索化if (!(pCur->pLchild))//前驱线索化{pCur->LTag = Thread; pCur->pLchild = pRe;}else{pCur->LTag = Link;}if (!(pRe->pRchild))//后继线索化{pRe->RTag = Thread; pRe->pRchild = pCur;}else{pRe->RTag = Link;}pRe = pCur;InThread(pCur->pRchild);//右子树线索化}}void InOrderThread(pBThrNode &pThr, pBThrNode pT){//中序线索化建线索二叉树/*****************处理头结点*********************/pThr = new BThrNode;pThr->LTag = Link;pThr->RTag = Thread;pThr->pRchild = pThr;if (!pT)pThr->pLchild = pThr;//由此至上皆为对头结点初始化else{pThr->pLchild = pT; // 由此至上皆为对头结点初始化pRe = pThr;/************************************************/InThread(pT);/*************处理中序遍历最后一个结点***********///完成后pRe指向中序遍历的最后一个结点,pCur==pRe->pRchild==NULL;pRe->pRchild = pThr;pRe->RTag = Thread;pThr->pRchild = pRe;//处理头结点/************************************************/}}pBThrNode GetPreNode(pBThrNode p){//当前节点左标签为线索,说明无左子树     //左指针域即指向其前驱 //当前节点左标签为链,说明有左子树     //找左子树根节点最右下的结点,即     //对其左子树中序遍历的最后一个结点,        //如果左子树的根节点无右子树,则指向    //左子树的根节点(当前节点的左指针域)    //即为所求,    //如果左子树的根节点有右子树,我们    //沿着左子树的根节点找最右下的结点    //即为所求pBThrNode pRe = p->pLchild;if (p->LTag == Link){while (pRe->RTag == Link){pRe = pRe->pRchild;}}return pRe;}pBThrNode GetPostNode(pBThrNode p){//当前结点无右子树,及p指向结点的右标签为Thread   //其右指针域值即为所求 //当前结点有右子树,及p指向结点的右标签为Link  //如果其右子树根结点无左子树,则指向当前结点右子树根     //的指针(当前结点的右指针域值)即为所求     //否则,沿着其右子树根一直往左走,当某个结点的左标签    //为线索时,说明指向该结点的指针值即为所求pBThrNode pPost = p->pRchild;if (p->RTag == Link){while (pPost->LTag == Link){pPost = pPost->pLchild;}}return pPost;}void Visit(ElemType c){cout << c << " ";}void PreOrderPrint(pBThrNode pT){if (pT){Visit(pT->data);PreOrderPrint(pT->pLchild);PreOrderPrint(pT->pRchild);}}void InOrderPrint(pBThrNode pT){if (pT){InOrderPrint(pT->pLchild);Visit(pT->data);InOrderPrint(pT->pRchild);}}void PostOrderPrint(pBThrNode pT){if (pT){PostOrderPrint(pT->pLchild);PostOrderPrint(pT->pRchild);Visit(pT->data);}}void InOrderThrPrint(pBThrNode pThr){pBThrNode pT = pThr->pLchild;//pT指向二叉树的根结点while (pT != pThr)//空树或遍历结束时,pT==pThr{while (pT->LTag == Link) //找到第一个结点pT = pT->pLchild;Visit(pT->data);while (pT->RTag == Thread&&pT->pRchild != pThr)//通过线索直接找到找到后继{//逻辑与第二个条件:不是最后一个结点pT = pT->pRchild,Visit(pT->data);}pT = pT->pRchild;//pT的右标签为Link,pT进至其右子树根(指向右子树根)}} int main(void){pBThrNode pThr,pT;PreCreate(pT);////ABD##E##CF##G##PreOrderPrint(pT);InOrderThread(pThr, pT);InOrderThrPrint(pThr);return 0;}




0 0
原创粉丝点击