【C语言学习】树的操作模板

#include<stdio.h>
#include<stdlib.h>

//链二叉树
typedef struct elementtype
{
    int tyint;
    char tychar;
}ElementType;

typedef struct tree
{
    int lTag;//用于线索化标记,为0则lChild为左孩子,为1,则lChild为前驱节点
    int rTag;//同上同理
    ElementType data;
    struct tree* lChild;
    struct tree* rChild;
}Tree;

Tree* pre=NULL;//定义全局变量pre,用于线索化

Tree* CreatNode(ElementType data)
{
    Tree* newtree=(Tree*)malloc(sizeof(Tree));
    newtree->data=data;
    newtree->lTag=0;
    newtree->rTag=0;
    newtree->lChild=NULL;
    newtree->rChild=NULL;
    return newtree;
}

void insertNode(Tree* parentNode,Tree* lChild,Tree* rChild)
{
    parentNode->lChild=lChild;
    parentNode->rChild=rChild;
}

void showCurData(Tree* myNode)
{
    if (myNode==NULL)
    {
        return;
    }
    printf("|%d %c|",myNode->data.tyint,myNode->data.tychar);
}

//递归遍历
void preOrder(Tree* root)
{
    if(root!=NULL)
    {
        showCurData(root);
        preOrder(root->lChild);
        preOrder(root->rChild);
    }
}

void midOrder(Tree* root)
{
    if(root!=NULL)
    {
        midOrder(root->lChild);
        showCurData(root);
        midOrder(root->rChild);
    }
}

void lastOrder(Tree* root)
{
    if(root!=NULL)
    {
        lastOrder(root->lChild);
        lastOrder(root->rChild);
        showCurData(root);
    }
}

void destory(Tree* root)
{
    if(root!=NULL)
    {
        lastOrder(root->lChild);
        lastOrder(root->rChild);
        free(root);
    }
}

//栈遍历
void preOrderByStack(Tree* root)
{
    if(root==NULL)
    {
        return;
    }
    Tree* pmove=root;
    struct tree* stack[100];
    int stackTop=-1;
    while (stackTop!=-1||pmove!=NULL)
    {
        while(pmove)//左走
        {
            showCurData(pmove);
            stack[++stackTop]=pmove;
            pmove=pmove->lChild;
        }
        if(stackTop!=-1)
        {
            pmove=stack[stackTop];
            stackTop--;
            pmove=pmove->rChild;
        }
    } 
}

void midOrderByStack(Tree* root)
{
    if(root==NULL)
    {
        return;
    }
    Tree* pmove=root;
    struct tree* stack[100];
    int stackTop=-1;
    while (stackTop!=-1||pmove!=NULL)
    {
        while(pmove)//左走
        {
            stack[++stackTop]=pmove;
            pmove=pmove->lChild;
        }
        if(stackTop!=-1)
        {
            pmove=stack[stackTop];
            showCurData(pmove);
            stackTop--; 
            pmove=pmove->rChild;
        }
    } 
}

void lastOrderByStack(Tree* root)
{
    if(root==NULL)
    {
        return;
    }
    Tree* pmove=root,* lastvist=NULL;
    struct tree* stack[100];
    int stacktop=-1;
    while(lastvist!=root)//只要没访问过根节点
    {
        while(pmove)//先左寻到底
        {
            stack[++stacktop]=pmove;
            pmove=pmove->lChild;
        }
        while(stacktop!=-1)
        {
            pmove=stack[stacktop--];
            if(pmove->rChild==NULL||pmove->rChild==lastvist)//返回时判断右节点是否访问过
            {//访问过就输出
                showCurData(pmove);
                lastvist=pmove;
            }
            else{//没访问过就进入右节点左寻
                stack[++stacktop]=pmove;
                pmove=pmove->rChild;
                while(pmove)
                {
                    stack[++stacktop]=pmove;
                    pmove=pmove->lChild;
                }
            }
        }
    }
}

//层次遍历
void floorOrder(Tree* root)
{
    if(root==NULL)
    {
        return;
    }
    int fornt,rear;
    Tree* queue[100],*pmove;
    fornt=rear=0;
    rear=(rear+1)%100;
    queue[rear]=root;
    while(fornt!=rear)
    {
        fornt=(fornt+1)%100;
        pmove=queue[fornt];
        showCurData(pmove);
        if(pmove->lChild!=NULL)
        {
            rear=(rear+1)%100;
            queue[rear]=pmove->lChild;
        }
        if(pmove->rChild!=NULL)
        {
            rear=(rear+1)%100;
            queue[rear]=pmove->rChild;
        }
    }
}

//线索化
void midThread(Tree* p)//中序线索化
{
    if(p!=NULL)
    {
        midThread(p->lChild);
        if(p->lChild==NULL)//左走到底,左空节点链至前节点
        {
            p->lChild=pre;
            p->lTag=1;
        }
        if(pre!=NULL&&pre->rChild==NULL)//又走到底,将当前节点链至前节点的又节点
        {
            pre->rChild=p;
            pre->rTag=1;
        }
        pre=p;
        midThread(p->rChild);
    }
}

void midOrderread(Tree* root)//中序线索化访问
{
    if(root!=NULL)
    {
        Tree* p=root;
        while(p!=NULL)//在没到底前
        {
            while(p->lTag==0)//左节点不是线索就一直向左访问
            {
                p=p->lChild;
            }
            showCurData(p);
            while(p->rTag==1&&p->rChild!=NULL)//右节点是后继节点且,不到底时,访问后继节点
            {
                p=p->rChild;
                showCurData(p);
            }
            p=p->rChild;
        }
    }
}

void preThread(Tree* p)//前序线索化
{
    if(p!=NULL)
    {
        if(p->lChild==NULL)//左走到底,左空节点链至前节点
        {
            p->lChild=pre;
            p->lTag=1;
        }
        if(pre!=NULL&&pre->rChild==NULL)//又走到底,将当前节点链至前节点的又节点
        {
            pre->rChild=p;
            pre->rTag=1;
        }
        pre=p;
        if(p->lTag==0) //若左节点是孩子则递归访问,防止访问线索化过的节点,打转
            preThread(p->lChild);
        if(p->rTag==0)
            preThread(p->rChild);
    }
}

void preOrderread(Tree* root)//前序线索化访问
{
    if(root!=NULL)
    {
        Tree* p=root;
        while(p!=NULL)//在没到底前
        {
            while(p->lTag==0)//左节点不是线索就一直向左访问
            {
                showCurData(p);
                p=p->lChild;
            }
            showCurData(p);//向左遇到线索就向右访问
            p=p->rChild;
        }
    }
}

void lastThread(Tree* p)//后序线索化
{
    if(p!=NULL)
    {
        lastThread(p->lChild);
        lastThread(p->rChild);
        if(p->lChild==NULL)//左走到底,左空节点链至前节点
        {
            p->lChild==pre;
            p->lTag=1;
        }
        if(pre!=NULL&&pre->rChild==NULL)//又走到底,将当前节点链至前节点的又节点
        {
            pre->rChild=p;
            pre->rTag=1;
        }
        pre=p;
    }
}

// 后序线索化访问,在建

int main()
{
    ElementType A={1,'a'};
    ElementType B={2,'b'};
    ElementType C={3,'c'};
    ElementType D={4,'d'};
    ElementType E={5,'e'};
    ElementType F={6,'f'};
    ElementType G={7,'g'};
    Tree* a=CreatNode(A);
    Tree* b=CreatNode(B);
    Tree* c=CreatNode(C);
    Tree* d=CreatNode(D);
    Tree* e=CreatNode(E);
    Tree* f=CreatNode(F);
    Tree* g=CreatNode(G);
    insertNode(a,b,c);
    insertNode(b,d,NULL);
    insertNode(d,NULL,g);
    insertNode(c,e,f);
    midOrder(a);
    puts("\n");
    midThread(a);
    midOrderread(a);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值