[数据结构] 严蔚敏版 线索二叉树C语言----惊为天人的按线索遍历算法

自己完全写不来,只能品一品其中的韵味。

源码来自这里!http://www.cnblogs.com/kangjianwei101/p/5237880.html

#ifndef THREADBINARYTREE_H
#define THREADBINARYTREE_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Status.h"

//线索二叉树类型定义
typedef char TElemType_Thr;
typedef enum {Link, Thread} PointerTag;
typedef struct ThrBiNode
{
    TElemType_Thr data;
    struct ThrBiNode *lchild;
    struct ThrBiNode *rchild;
    struct ThrBiNode *parent;
    PointerTag LTag;
    PointerTag RTag;

} ThrBiNode, *ThrBiTree;

//函数列表
Status CreateBiTree_Thr (FILE *fp, ThrBiTree *T);

void InThreading_Thr (ThrBiTree p);
//中序线索化

Status CreateBiTreebyStr (ThrBiTree *T, char *ch, int *num);

Status InOrderThreading_Thr (ThrBiTree *Thrt, ThrBiTree T);
//中序遍历并线索化

Status InOrderTraversebyThread (ThrBiTree Thrt,void (Visit)(TElemType_Thr));

void PreThreading_Thr (ThrBiTree p);

Status PreOrderThreading_Thr (ThrBiTree *Thrt, ThrBiTree T);

Status PreOrderTraversebyThread (ThrBiTree Thrt,void (Visit)(TElemType_Thr));

void PostThreading_Thr (ThrBiTree p);

Status PostOrderThreading_Thr (ThrBiTree *Thrt, ThrBiTree T);

Status PostOrderTraversebyThread (ThrBiTree Thrt,void (Visit)(TElemType_Thr));

void ParentPointer_Thr (ThrBiTree Thrt);

ThrBiTree Post_NextPtr_Thr (ThrBiTree Thrt, ThrBiTree p);
//为后序遍历寻找结点后序提供帮助

void OutputbyStr_Tri (ThrBiTree T); //中序输出测试

Status InOrderTraverse (ThrBiTree Thrt,void (Visit)(TElemType_Thr));
#endif // THREADBINARYTREE_H
#ifndef THREADBINARYTREE_C
#define THREADBINARYTREE_C

#include "ThreadBinaryTree.h"

线索二叉树类型定义
//typedef char TElemType_Thr
//typedef enum {Link, Thread} PointerTag;
//typedef struct ThrBiNode
//{
//    TElemType_Thr data;
//    struct ThrBiNode *lchild;
//    struct ThrBiNode *rchild;
//    struct ThrBiNode *parent;
//    PointerTag LTag;
//    PointerTag RTag;
//
//} ThrBiNode, *ThrBiTree;

ThrBiTree pre;

//函数列表
Status CreateBiTree_Thr (FILE *fp, ThrBiTree *T)
{
    TElemType_Thr ch[15];
    fscanf(fp,"%s",ch);
    if (strcmpi(ch,"PreOrderTree")==0){
        fscanf(fp,"%s",ch);
        int num = 0;
//        printf("\nch = %s\n",ch);
        CreateBiTreebyStr (T,ch,&num);

//        OutputbyStr_Tri(*T);
        return OK;
    } else {

        return ERROR;
    }
}

void OutputbyStr_Tri (ThrBiTree T)
{
    if (T){
        printf("%c",T->data);
        OutputbyStr_Tri(T->lchild);
        OutputbyStr_Tri(T->rchild);
    } else {
        printf("^");
    }
}

Status CreateBiTreebyStr (ThrBiTree *T, char *ch, int *num)
{
    if (ch[*num]=='^'){
        *T = NULL;
        (*num)++;
    }
    else {
        *T = (ThrBiTree)malloc(sizeof(ThrBiNode));
        if(!*T)
            exit (OVERFLOW);
        (*T)->data = ch[*num];
        (*num)++;
        CreateBiTreebyStr(&(*T)->lchild,ch,num);
        if ((*T)->lchild)
            (*T)->LTag = Link;
        else
            (*T)->LTag = Thread;

        CreateBiTreebyStr(&(*T)->rchild,ch,num);
        if((*T)->rchild)
            (*T)->RTag = Link;
        else
            (*T)->RTag = Thread;
    }
    return OK;
}

void InThreading_Thr (ThrBiTree p)
{ //与中序遍历的结构类似
    if (p){
        InThreading_Thr(p->lchild);// 线索化左子树
        if (!p->lchild){ //为当前结点左子树建立前驱线索
            p->LTag = Thread;
            p->lchild = pre;
        }
        if (!pre->rchild){ //为上一个结点右子树建立后驱线索
            pre->RTag = Thread;
            pre->rchild = p;
        }
        pre = p; //pre挪到当前位置

        InThreading_Thr(p->rchild); //线索化右子树
    }
}
//中序线索化

Status InOrderThreading_Thr (ThrBiTree *Thrt, ThrBiTree T)
{
    *Thrt = (ThrBiTree)malloc(sizeof(ThrBiNode));
    if (!*Thrt)
        exit(OVERFLOW);
    (*Thrt)->data = '\0';
    (*Thrt)->LTag = Link;
    (*Thrt)->RTag = Thread;
    (*Thrt)->rchild = *Thrt;

    if (!T)
        (*Thrt)->lchild = *Thrt;
    else {
            //第一个结点指向thrt,thrt后继指向最后一个结点,建立双向联系
        (*Thrt)->lchild = T;
        pre = *Thrt;
        InThreading_Thr(T);
        pre->RTag = Thread;
        pre->rchild = *Thrt;
        (*Thrt)->rchild = pre;
    }
    return OK;
}
//中序遍历并线索化

Status InOrderTraversebyThread (ThrBiTree Thrt,void (Visit)(TElemType_Thr))
{
    ThrBiTree p = Thrt->lchild;

    while (p!=Thrt){
        while (p->LTag==Link)
            p = p->lchild;
        Visit(p->data);
        while (p->RTag==Thread && p->rchild!=Thrt){
            p = p->rchild;
            Visit(p->data);
        }
        p = p->rchild;
    }
    return OK;
}

Status InOrderTraverse (ThrBiTree Thrt,void (Visit)(TElemType_Thr))
{
    if (Thrt){
        if (Thrt->LTag==Link){
            InOrderTraverse(Thrt->lchild,Visit);
        }
        Visit(Thrt->data);
        if (Thrt->RTag==Link){
            InOrderTraverse(Thrt->rchild,Visit);
        }
    }
}

void PreThreading_Thr (ThrBiTree p)
{
    if (p){
        if (!pre->rchild){
            //为上一个结点的右子树建立后继线索
            pre->RTag = Thread;
            pre->rchild = p;
        }
        pre = p;
        PreThreading_Thr(p->lchild); //线索化左子树
        if (p->rchild && p->RTag==Link)
            PreThreading_Thr(p->rchild); //线索化右子树
    }
}

Status PreOrderThreading_Thr (ThrBiTree *Thrt, ThrBiTree T)
{
    *Thrt = (ThrBiTree)malloc (sizeof(ThrBiNode));
    if (!*Thrt)
        exit (OVERFLOW);
    (*Thrt)->data = '\0';
    (*Thrt)->LTag = Link;
    (*Thrt)->RTag = Thread;
    (*Thrt)->rchild = NULL;
    if (!T)
        (*Thrt)->lchild = (*Thrt)->rchild = *Thrt;
    else {
        (*Thrt)->lchild = T;
        pre = *Thrt;

        PreThreading_Thr(T);

        pre->RTag = Thread;
        pre->rchild = *Thrt;
    }
    return OK;
}
Status PreOrderTraversebyThread (ThrBiTree Thrt,void (Visit)(TElemType_Thr))
{
    ThrBiTree p = Thrt;
    while (p->rchild!=Thrt){
        while (p->lchild){
            p = p->lchild;
            Visit(p->data);
        }
        if (p->rchild!=Thrt){
            p = p->rchild;
            Visit(p->data);
        }
    }
    return OK;
}

void PostThreading_Thr (ThrBiTree p)
{
    if (p){
        if (!p->rchild){
            //为当前结点右子树建立后继线索
            p->RTag = Thread;
            p->rchild = pre;
        }
        pre = p; //pre在正常顺序中为后一个结点
        if (p->RTag!=Thread)
            PostThreading_Thr(p->rchild); //线索化右子树

        PostThreading_Thr(p->lchild); //线索化左子树
    }
}

Status PostOrderThreading_Thr (ThrBiTree *Thrt, ThrBiTree T)
{
    *Thrt = (ThrBiTree)malloc(sizeof(ThrBiNode));
    if (!*Thrt)
        exit (OVERFLOW);
    (*Thrt)->data = '\0';
    (*Thrt)->LTag = Link;
    (*Thrt)->RTag = Thread;
    (*Thrt)->rchild = *Thrt;

    if (!T)
        (*Thrt)->lchild = *Thrt;
    else {
        (*Thrt)->lchild = T;
        pre = *Thrt;
        PostThreading_Thr(T);
        (*Thrt)->rchild = T; //头结点回指
    }
    return OK;
}

Status PostOrderTraversebyThread (ThrBiTree Thrt,void (Visit)(TElemType_Thr))
{
    ThrBiTree p = Thrt->lchild;
    if(p!=Thrt){
        while(1){ //寻找遍历起点
            while (p->lchild)
                p = p->lchild;
            if (p->rchild && p->RTag!=Thread)
                p = p->rchild;
            else
                break;
        }
        while (p){
            Visit(p->data);
            p = Post_NextPtr_Thr(Thrt,p);
        }
    }
    return OK;
}

void ParentPointer_Thr (ThrBiTree T)
{
    ThrBiTree node[100];
    int i,j;
    i=j=0;
    if (T)
        node[j++] = T;
    node[i]->parent = NULL;
    while (i<j){
        if (node[i]->lchild){
            node[j++] = node[i]->lchild;
            node[i]->lchild->parent = node[i];
        }
        if (node[i]->rchild){
            node[j++] = node[i]->rchild;
            node[i]->rchild->parent = node[i];
        }
        i++;
    }
}

ThrBiTree Post_NextPtr_Thr (ThrBiTree Thrt, ThrBiTree p)
{
    //寻找p的后继
    if (p==Thrt->lchild) //根节点是最后一个结点
        return NULL;
    else {
        if (p->RTag==Thread)
            return p->rchild; //右孩子为线索
        else {
            if (p==p->parent->rchild) //当前结点是左孩子
                return p->parent;
            else{
                if (p->parent->RTag!=Link)
                    p = p->parent; //双亲结点没有右孩子
                else {
                    p = p->parent->rchild;
                    while (1){ //寻找右兄弟遍历起点
                        while (p->lchild)
                            p = p->lchild;
                        if (p->rchild && p->RTag!=Thread)
                            p = p->rchild;
                        else
                            break;
                    }
                }
                return p;
            }
        }
    }

}//为后序遍历寻找结点后序提供帮助

#endif // THREADBINARYTREE_C
#include <stdio.h>
#include <stdlib.h>

#include "ThreadBinaryTree.h"

void PrintElem (TElemType_Thr e);

int main(int argc, char **argv)
{
    ThrBiTree Thrt1,Thrt2,Thrt3,T1,T2,T3;
    int mark;

    printf("按先序序列创建二叉树\n");
    FILE *fp = fopen("TestData_T.txt","r");
    CreateBiTree_Thr(fp,&T1);
    fseek(fp,0,SEEK_SET);
    CreateBiTree_Thr(fp,&T2);
    fseek(fp,0,SEEK_SET);
    CreateBiTree_Thr(fp,&T3);
    fclose(fp);
    printf("\n");
//    OutputbyStr_Tri(T1);
//    OutputbyStr_Tri(T2);
    printf("测试先序后继线索二叉树\n");
    printf("将T1先序后继线索化为Thr1\n");
    PreOrderThreading_Thr(&Thrt1,T1);
    printf("\n");
    printf("先序遍历Thr1 = ");
    PreOrderTraversebyThread(Thrt1,PrintElem);


    printf("\n将T2中序全线索化为Thrt2\n");
    InOrderThreading_Thr(&Thrt2,T2);
    printf("中序遍历Thrt2 = ");
    InOrderTraversebyThread(Thrt2,PrintElem);
//    printf("\nOld-School Traverse = ");
//    InOrderTraverse(Thrt2->lchild,PrintElem);
//    printf("\n,Thrt2 data = %c",Thrt2->data);
    printf("\n");

    printf("为T3各结点寻找双亲结点\n");
    ParentPointer_Thr(T3);
    printf("\n");

    printf("将T3后序后继线索化为Thrt3\n");
    PostOrderThreading_Thr(&Thrt3,T3);
    printf("\n");

    printf("后序遍历线索化的Thrt3\n");
    PostOrderTraversebyThread(Thrt3,PrintElem);
    printf("\n");

    return 0;
}

void PrintElem (TElemType_Thr e)
{
    printf("%c",e);
}
txt: PreOrderTree ABDG^^^EH^^I^^CF^J^^^

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值