树的遍历(递归与非递归版本)

来源:互联网 发布:如何建立网络平台 编辑:程序博客网 时间:2024/05/19 19:14

树的遍历

题目要求

要求4个函数分别按照访问顺序打印出结点的内容,格式为一个空格跟着一个字符。

#include <stdio.h>#include <stdlib.h>typedef char ElementType;typedef struct TNode *Position;typedef Position BinTree;struct TNode{    ElementType Data;    BinTree Left;    BinTree Right;};BinTree CreatBinTree(); /* 实现细节忽略 */void InorderTraversal( BinTree BT );void PreorderTraversal( BinTree BT );void PostorderTraversal( BinTree BT );void LevelorderTraversal( BinTree BT );int main(){    BinTree BT = CreatBinTree();    printf("Inorder:");    InorderTraversal(BT);    printf("\n");    printf("Preorder:");   PreorderTraversal(BT);   printf("\n");    printf("Postorder:");  PostorderTraversal(BT);  printf("\n");    printf("Levelorder:"); LevelorderTraversal(BT); printf("\n");    return 0;}/* 你的代码将被嵌在这里 */

前序中序后续:递归版本

//递归版本void InorderTraversal( BinTree BT ){    if (BT == NULL) {        return;    }    InorderTraversal(BT->Left);    printf(" %c", BT->Data);    InorderTraversal(BT->Right);}void PreorderTraversal( BinTree BT ){    if (BT == NULL) {        return;    }    printf(" %c", BT->Data);    PreorderTraversal(BT->Left);    PreorderTraversal(BT->Right);}void PostorderTraversal( BinTree BT ){    if (BT == NULL) {        return;    }    PostorderTraversal(BT->Left);    PostorderTraversal(BT->Right);    printf(" %c", BT->Data);}

前中后序遍历:非递归版本,利用栈。

树的遍历

总体思路:

1.前序和中序

遇到一个结点,就把它压栈,并去遍历它的左子树;

当左子树遍历结束后,从栈顶弹出这个结点;

然后按其右指针再去中序遍历该结点的右子树。

前序和中序的不同点就是在不同的时刻去访问(或者叫打印)结点。

2.后序遍历

利用两个栈,第一个栈pop出来的数据全部push到第二个栈中。
具体操作就是:

  1. 先将根结点入栈s1

  2. s1弹出根结点

  3. s1弹出的结点push到s2中。

  4. 将根节点的左、右结点(如果非空)入栈s1。

  5. 循环2-4步,直到s1中为空。

6.最后将s2中的结点全部出栈并打印。

根据上面的步骤可知,从s1中弹出的顺序(也就是进入s2的顺序)为 ++根 右 左++,那么 从s2中出栈的顺序就是 ++左 右 根++。

//利用栈进行前中后序遍历struct MyStack{    BinTree data[10000];    int top;};typedef struct MyStack* Stack;int isEmptyStack(Stack s){    if(s->top == -1){        return 1;    } else {        return 0;    }}void push(Stack s, BinTree tree){    s->data[++(s->top)] = tree;}BinTree pop(Stack s){    if (isEmptyStack(s)) {        return NULL;    }    return s->data[(s->top)--];}void PreorderTraversal( BinTree BT ){    Stack s = (Stack)malloc(sizeof(struct MyStack));    s->top = -1;    BinTree tmpTree = BT;    while (tmpTree || !isEmptyStack(s)) {        //遇到一个结点(访问),就把它压栈,并去遍历它的左子树;        while (tmpTree) {            printf(" %c", tmpTree->Data);            push(s, tmpTree);            tmpTree = tmpTree->Left;        }        //左子树遍历结束后,从栈顶弹出,再去访问右子树        if (!isEmptyStack(s)) {            tmpTree = pop(s);            tmpTree = tmpTree->Right;        }    }}void InorderTraversal( BinTree BT ){    Stack s = (Stack)malloc(sizeof(struct MyStack));    s->top = -1;    BinTree tmpTree = BT;    while (tmpTree || !isEmptyStack(s)) {        while (tmpTree) {            push(s, tmpTree);            tmpTree = tmpTree->Left;        }        if (!isEmptyStack(s)) {            tmpTree = pop(s);            printf(" %c", tmpTree->Data);            tmpTree = tmpTree->Right;        }    }}void PostorderTraversal( BinTree BT ){    Stack s1 = (Stack)malloc(sizeof(struct MyStack));    s1->top = -1;    Stack s2 = (Stack)malloc(sizeof(struct MyStack));    s2->top = -1;    if(BT)  push(s1, BT);       //先将根结点入栈    BinTree tmpTree;    while (!isEmptyStack(s1)) {        tmpTree = pop(s1);      //弹出根结点        push(s2, tmpTree);      //从s1弹出的push到s2中        //将根结点的左右子节点入栈。        if(tmpTree->Left)   push(s1, tmpTree->Left);        if(tmpTree->Right)  push(s1, tmpTree->Right);    }    while (!isEmptyStack(s2)) {        printf(" %c", pop(s2)->Data);    }}

层序遍历:利用队列

步骤:
1. 先将根节点入队。
2. 执行循环:结点出队,访问结点,再将结点的左右子结点(如果非空)入队。
3. 直到队列为空,停止循环。

struct myQueue{    BinTree data[10000];    int head;    int tail;};typedef struct myQueue* PosQueue;int isEmpty(PosQueue que){    if(que->head == que->tail){        return 1;    }    return 0;}void push(PosQueue que, BinTree tree){    que->tail = (que->tail + 1)%10000;    que->data[que->tail] = tree;}BinTree pop(PosQueue que){    if (isEmpty(que)) {        return NULL;    }    que->head = (que->head+1)%10000;    return que->data[que->head];}void LevelorderTraversal( BinTree BT ){    if (BT == NULL) {        return;    }    PosQueue que = (PosQueue)malloc(sizeof(struct myQueue));    que->head = -1;    que->tail = -1;    push(que, BT);    while (!isEmpty(que)) {        BinTree tree = pop(que);        printf(" %c", tree->Data);        if(tree->Left != NULL)  push(que, tree->Left);        if(tree->Right != NULL)push(que, tree->Right);    }}
原创粉丝点击