中序线索化二叉树

来源:互联网 发布:php手机验证码 编辑:程序博客网 时间:2024/06/05 02:15
#include<stdio.h>#include<stdlib.h>#define ENDMARK 0//树叶子结束标志#define datatype inttypedef enum{link,thread} tagtype;//定义枚举性tagtype typedef struct treenode//定义树结点结构体{    datatype num;    struct treenode * lchild;    struct treenode * rchild;    tagtype ltag,rtag;//左右标记位}treenode,*treeptr;void creat_tree(treeptr * tree);//前序遍历,建立二叉树void visit(treeptr tree);//访问结点void InOrderTranverse(treeptr tree);//中序遍历二叉树void InOrderThread(treeptr tree,treeptr * pre);//中序线索化void InOrderThreading(treeptr * thead, treeptr tree);//添加头结点,实现中序线索化,形成循环链表void InOrderThreading_Tranverse(treeptr thead);//利用非递归的方式遍历二叉树void main(){    treeptr t,thead;    creat_tree(&t);    printf("tree not threaded is:\n");    InOrderTranverse(t);    printf("threaded tree is:\n");    InOrderThreading(&thead, t);//添加头结点,实现中序线索化,形成循环链表    InOrderThreading_Tranverse(thead);    system("pause");}void creat_tree(treeptr * tree)//前序遍历,建立二叉树{    datatype temp;    treeptr newnode;    scanf("%d",&temp);    if (temp==ENDMARK)    {        (*tree)=NULL;//结束        return;    }    else    {        newnode = (treeptr)malloc(sizeof(treenode));//创建新结点及结点初值化        newnode->num = temp;        newnode->ltag = link;//初值皆为link        newnode->rtag = link;        *tree = newnode;        creat_tree(&(*tree)->lchild);//遍历左子树        creat_tree(&(*tree)->rchild);//遍历右子树            }}void InOrderTranverse(treeptr tree)//中序遍历二叉树{    if (tree==NULL)    {        return;    }    else    {        InOrderTranverse(tree->lchild);//遍历左子树        visit(tree);        InOrderTranverse(tree->rchild);//遍历左子树    }}void visit(treeptr tree)//访问结点{    printf("%p,%p,%p,%d,%d,%d\n",tree,tree->lchild,tree->rchild,tree->num,tree->ltag,tree->rtag);}/*中序线索化二叉树其实就是  将结点中的空指针改为指向  前驱结点或后继结点的指针,  从而将二叉树改为一个循环  链表*/void InOrderThread(treeptr tree,treeptr * pre)//中序线索化{    if (tree)    {        InOrderThread(tree->lchild, pre);//遍历左子树,找到该节点的最左边的叶子开始        if(!tree->lchild)        {            tree->lchild=*pre;            tree->ltag = thread;        }           if(!(*pre)->rchild)        {            (*pre)->rchild = tree;            (*pre)->rtag = thread;        }        (*pre)=tree;//当前结点为pre        InOrderThread(tree->rchild, pre);//遍历由子树,找到该节点的最左边的叶子开始    }}void InOrderThreading(treeptr * thead, treeptr tree)//添加头结点,实现中序线索化,形成循环链表{    treeptr newnode,pre;    newnode = (treeptr)malloc(sizeof(treenode));    *thead = newnode;     (*thead)->rchild = (*thead);//指定右孩子,非空    (*thead)->rtag = thread;    (*thead)->ltag = link;    if (!tree)    {        (*thead)->lchild = (*thead);    }    else    {        (*thead)->lchild = tree;//添加头结点    }    pre = (*thead);    InOrderThread(tree, &pre);//中序线索化二叉树    pre->rchild = (*thead);    pre->rtag = thread;    (*thead)->rchild = pre;}void InOrderThreading_Tranverse(treeptr thead)//利用非递归的方式遍历线索化后的二叉树{    treeptr tree;    tree = thead->lchild;    while(tree!=thead)    {        while(tree->ltag==link)        {            tree = tree->lchild;//遍历到该节点下最左边的叶子        }        visit(tree);        while(tree->rtag==thread&&tree->rchild!=thead)//到下一个含有右子树的根节点        {            tree = tree->rchild;            visit(tree);        }        tree = tree ->rchild;//找到右子树叶子    }}
0 0
原创粉丝点击