树的基本算法(C语言版)

来源:互联网 发布:javascript url编码 编辑:程序博客网 时间:2024/06/01 09:49

先序次序创建二叉树

status CreateBiTree(BiTree &T){    char a;    scanf("%c",&a);    if(a=='#')        T=null;    else    {        T=(BiTNode)malloc(sizeof(BiNode));        if(!T)            exit(0);        T->data=a;        CreateBiTree(T->lchild);        CreateBiTree(T->rchild);            }}

销毁二叉树

    status DestroyTree(BiTree &T)    {        if(T->data==null)            exit(0);            free(T);            T=null;    }

清除二叉树,使之变成一棵空树

status ClearBiTree(BiTree &T){    if(T!=null)    {        ClearBiTree(T->lchild);        ClearBiTree(T->rchild);        free(T);        T=null;         }}

求二叉树的高度(深度)(递归)

int DepthBiTree(BiTree &T){    if(t==null)        return 0;    else if(T->lchild==null&&T->rchild==null)        return 1;    else    {        int dep1=DepthBiTree(T->lchild);        int dep2=DepthBiTree(T->rchild);        if(dep1>dep2)            return dep1+1;        else            return dep2+1;    }}

二叉树的叶子结点数

int leaf(BiTree &T){    int n1,n2;    if(T==NULL)        return 0;    else if(T->lchild==null&&T->rchild==null)        return 1;    else    {        n1=leaf(T->lchild);        n2=leaf(T->rchild);        return n1+n2;    }}

二叉树总结点数

int nodes(BiTree &T){    int n1,n2;    if(T==null)        return 0;    else if(T->rchild==null&&T->lchild==NULL)        return 1;    else    {        n1=nodes(T->lchild);        n2=nodes(T->rchild);        return n1+n2+1;    }}

度为1的结点数

int node1(BiTree &T){    int n1,n2,n=0;    if(T==NULL)        return 0;    else    {        if(T->lchild&&T->rchild==NULL||T->rchild&&T->lchild==NULL)            n=1;        n1=node1(T->lchild);        n2=node2(T->rchild);        return n1+n2+n;    }}

度为2的结点数

    int n1,n2,n=0;    if(T==NULL)        return 0;    else    {        if(T->lchild&&T->rchild)            return 1;        n1=node2(T->lchild);        n2=node2(T->rchild);        return n1+n2+n;    }}

交换二叉树所有左右子树

void exchange(BiTree &T){    BiTNode *temp;    if(T)    {        temp=T->lchild;        T->lchild=T->rchild;        T->rchild=temp;        exchange(T->lchild);        exchange(T->rchild);    }}

先序遍历(递归算法)

void PreOrder(BiTree &T){    if(T)    {        printf("%c",T->data);        PreOrder(T->lchild);        PreOrder(T->rchild);    }}

中序遍历(递归算法)

void InOrder(BiTree &T){    if(T)    {        PreOrder(T->lchild);            printf("%c",T->data);        PreOrder(T->rchild);    }}

后序遍历(递归算法)

void InOrder(BiTree &T){    if(T)    {        PreOrder(T->lchild);            PreOrder(T->rchild);        printf("%c",T->data);    }}

先序遍历(非递归算法)

void PreOrder(BiTree &T){    Stack s;    StackInit(s);    BiTree *p=NULL;    while(p||!StackEmpty(s))    {        while(P)        {            visit(P->data);            push(s,p);            p=p->lchild;        }        if(!StackEmpty(s))        {            pop(s,p);            p=p->rchild;        }    }}

中序遍历(非递归算法)

void InOrder(BiTree &T){    Stack s;    StackInit(s);    BiTree *p=NULL;    while(p||!StackEmpty(s))    {        while(P)        {            push(s,p);            p=p->lchild;        }        if(!StackEmpty(s))        {            pop(s,p);            visit(P->data);                     p=p->rchild;        }    }}

后序遍历(非递归算法)

void PostOrder(BiTree &T){    InitStack(S);    P=T;    r=null;    while(p||!StackEmpty(s))    {        if(p)        {            push(s,p);            p=p->lchild;        }        else        {            GetTop(s,p);            if(p->rchild&&p->rchild!=r)            {                p=p->rchild;                push(s,p);                p=p->lchild;            }            else            {                pop(s,p);                visit(p->data);                r=p;                p=NULL;            }        }    }}

后序遍历的算法思想

因为后序非递归遍历二叉树的顺序是先访问左子树,再访问右子树,最后访问根结点,当用栈来存储结点必分清返回根结点时是从左或事右子树返回,所以,使用辅助指针r,其指向最近访问过的结点。也可以在结点中加入标志域,记录是否被访问过。

层次遍历(借助队列)

void LevelOrder(BiTree &T){    InitQueue(Q);                //初始化辅助队列    BiTree p;    EnQueue(Q,T);               //将根结点入队    while(!QueueEmpty(Q))       //队列不空循环    {        DeQueue(Q,p);           //队头元素出队        visit(P);               //访问当前p所指向结点        if(p->lchild!=NULL)            EnQueue(Q,p->lchild);  //左子树不空,则左子树入队列        if(p->rchild!=NULL)       //右子树不空,右子树入队列            EnQueue(Q,p->rchild);    }}
0 0