回 帖 发 新 帖 刷新版面

主题:求助线索二叉数的算法

向高手求助,希望能给出一个完整的线索二叉树的算法,这个困惑了小弟有几天了,希望能够得到解决!

回复列表 (共4个回复)

沙发

线索:二叉树中无左子树的结点,左指针指向其前驱,并设标志位;无右子树,右指针指向其后继!!
是在遍历二叉树时进行指针修改的,结果是没有空指针!
刚看书看到的!

板凳


里面有线索二叉树的函数,还有找前驱和后继.自己看看吧!
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct BiThrNode
   {    ElemType     data;
        struct BiThrNode  *lchild, *rchild;//左、右孩子指针
        int   ltag, rtag;//左右孩子线索标记 
   }BiThrNode,    *BiThrTree;
BiThrTree pre=NULL;//全局前驱节点
//创建二叉链表
BiThrTree  CreatBiThrTree()
{    
    ElemType  x;
    BiThrTree  T;
    scanf("%d",&x);
    if(x==-1) T=NULL;
    else
       {    T=(BiThrTree)malloc(sizeof(BiThrNode));
            T->data=x; //生成根结点
            printf("%d的左节点为:",x);
            T->lchild=CreatBiThrTree(); //生成左子树
            printf("%d的右节点为:",x);
            T->rchild=CreatBiThrTree(); //生成右子树
        }
    return T;
   }
//二叉链表线索化
void InOrderThreat(BiThrTree T)
{if (T)
     {    InOrderThreat(T->lchild);   //左子树中序线索化
        if (T->lchild==NULL){
            T->ltag=1;
            T->lchild=pre; 
            } //p的左孩子为空时,置左标记,左线索为pre;
        else T->ltag=0;
        if (T->rchild==NULL) T->rtag=1;//p的右孩子为空时,置右标记,为右线索作准备
        else T->rtag=0;
        if (pre!=NULL && pre->rtag==1)     pre->rchild=T;//若pre不为空,给pre加后继线索
        printf("当前访问节点为:%d\n",T->data);
        pre=T;//前驱指针后移
        InOrderThreat(T->rchild); //右子树中序线索化
     }
 }//结束InOrderThreat
//查找节点p的前驱节点
BiThrTree InorderPre(BiThrTree  p)
{
    BiThrTree  q;
    //结点的左子树为空时,结点的左指针域为左线索,指向其前驱
    if (p->ltag==1)        q=p->lchild;
    //结点的左子树非空时,从节点的左孩子出发,直到找到没有右孩子的节点为止
    else
    {
        q=p->lchild; //p结点的中序前驱是左子树中最右边结点
        while (q->rtag==0 )  q=q->rchild;
    }
    if(q!=NULL)    printf("节点的前驱节点为:%d\n",q->data);
    else printf("节点的前驱节点为空!\n");
    return (q);
 }

//查找节点p的后继节点
BiThrTree  InorderNext(BiThrTree  p)
{
    BiThrTree  q; 
    //结点的右子树为空,结点的右指针域为右线索,指向其后继
    if (p->rtag==1)    q=p->rchild;
    //结点的右子树非空时,从节点的右孩子出发,直到找到没有左孩子的节点为止
    else 
    {
        q=p->rchild; //P结点的中序后继是其右子树中最左边结点 
        while (q->ltag==0 )  q=q->lchild; 
    }
    if(q!=NULL) printf("节点的后继节点为:%d\n",q->data);
    else printf("节点的后继节点为空!\n");
    return (q);
 } 

main()
 {
    BiThrTree T;
    BiThrTree temp;
    int i;
    printf("----------------------创建二叉树!--------------------\n");
    printf("输入第一个节点:\n");
    T=CreatBiThrTree();
    printf("-------------------中序线索化二叉树!--------------------\n");
    InOrderThreat(T);
    temp=T;
    printf("获取temp节点的左右节点,输入1获取左节点,2获取右节点,0停止操作!\n");
    scanf("%d",&i);
    while(i!=0){
        if(i==1){
            if(temp->lchild!=NULL)    temp=temp->lchild;
            else printf("temp没有左节点!\n");
            printf("当前节点为:%d\n",temp->data);
            InorderPre(temp);
            InorderNext(temp);
        }
        else if(i==2){
            if(temp->rchild!=NULL)    temp=temp->rchild;
            else printf("temp没有右节点!\n");
            printf("当前节点为:%d\n",temp->data);
            InorderPre(temp);
            InorderNext(temp);
        }
        scanf("%d",&i);
    }

 }

3 楼

收藏ING

4 楼

大哥,你的程序是死循环啊???!!!

我来回复

您尚未登录,请登录后再回复。点此登录或注册