二叉树 (Binary Tree)的遍历

来源:互联网 发布:ubuntu 桌面程序开发 编辑:程序博客网 时间:2024/05/18 21:08

树是一种比较重要的数据结构,尤其是二叉树。二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

二叉树节点定义:

#define ElementType chartypedef struct Node {    ElementType data;    struct Node *lchild;    struct Node *rchild;}BinaryTree;


一、二叉树遍历递归遍历算法

1.先序遍历递归遍历算法

/* (1)先序遍历 递归解法 遍历过程为:    1.访问根节点    2.遍历其左子树    3.遍历其右子树*/void PreOrderTraversal(BinaryTree* BT) {    if (BT) {        printf("%c", BT->data);        PreOrderTraversal(BT->lchild);        PreOrderTraversal(BT->rchild);    }}


2.中序遍历递归遍历算法

/* (2)中序遍历 递归解法 遍历过程:    1.遍历其左子树    2.访问根节点    3.遍历其右子树*/void InOrderTraversal(BinaryTree* BT) {    if (BT) {        InOrderTraversal(BT->lchild);        printf("%c", BT->data);        InOrderTraversal(BT->rchild);    }}


3.后序遍历递归遍历算法

/* (3)后序遍历 递归解法 遍历过程:    1.遍历其左子树    2.遍历其右子树    3.访问根节点*/void PostOrderTraversal(BinaryTree* BT) {    if (BT) {        PostOrderTraversal(BT->lchild);        PostOrderTraversal(BT->rchild);        printf("%c", BT->data);    }}


验证如下:

#include <stdio.h>#include <stdlib.h>#define ElementType chartypedef struct Node {    ElementType data;    struct Node *lchild;    struct Node *rchild;}BinaryTree;//创建二叉树节点BinaryTree* CreateBinaryTree(data) {    BinaryTree* t = (BinaryTree*)malloc(sizeof(BinaryTree));    if (!t) {        printf("空间不足!\n");        return NULL;    }    t->lchild = NULL;    t->rchild = NULL;    t->data = data;    return t;}/* (1)先序遍历 递归解法 遍历过程为:    1.访问根节点    2.遍历其左子树    3.遍历其右子树*/void PreOrderTraversal(BinaryTree* BT) {    if (BT) {        printf("%c", BT->data);        PreOrderTraversal(BT->lchild);        PreOrderTraversal(BT->rchild);    }}/* (2)中序遍历 递归解法 遍历过程:    1.遍历其左子树    2.访问根节点    3.遍历其右子树*/void InOrderTraversal(BinaryTree* BT) {    if (BT) {        InOrderTraversal(BT->lchild);        printf("%c", BT->data);        InOrderTraversal(BT->rchild);    }}/* (3)后序遍历 递归解法 遍历过程:    1.遍历其左子树    2.遍历其右子树    3.访问根节点*/void PostOrderTraversal(BinaryTree* BT) {    if (BT) {        PostOrderTraversal(BT->lchild);        PostOrderTraversal(BT->rchild);        printf("%c", BT->data);    }}int main(int argc, const char * argv[]) {    BinaryTree* tree_A = CreateBinaryTree('A');        BinaryTree* tree_B = CreateBinaryTree('B');    tree_A->lchild = tree_B;        BinaryTree* tree_C = CreateBinaryTree('C');    tree_A->rchild = tree_C;        BinaryTree* tree_D = CreateBinaryTree('D');    tree_B->lchild = tree_D;        BinaryTree* tree_F = CreateBinaryTree('F');    tree_B->rchild = tree_F;        BinaryTree* tree_E = CreateBinaryTree('E');    tree_F->lchild = tree_E;        BinaryTree* tree_G = CreateBinaryTree('G');    tree_C->lchild = tree_G;        BinaryTree* tree_I = CreateBinaryTree('I');    tree_C->rchild = tree_I;        BinaryTree* tree_H = CreateBinaryTree('H');    tree_G->rchild = tree_H;        //先序遍历 => A B D F E C G H I    PreOrderTraversal(tree_A);        printf("\n");        //中序遍历 => D B E F A G H C I    InOrderTraversal(tree_A);        printf("\n");        //后序遍历 => D E F B H G I C A    PostOrderTraversal(tree_A);        return 0;}



二、二叉树遍历非递归遍历算法

非递归算法实现的基本思路:使用栈

1.遇到一个节点,就把它压栈,并去遍历它的左子树。

2.当左子树遍历结束后,从栈顶弹出这个节点并访问它。

3.然后按其右指针再去遍历该节点的右子树。

#include <stdio.h>#include <stdlib.h>#define ElementType chartypedef struct Node {    int isFirst;    ElementType data;    struct Node *lchild;    struct Node *rchild;}BinaryTree;typedef struct StackNode {    BinaryTree* data;    struct StackNode* next;}Stack;//初始化堆栈Stack* CreateStack() {    Stack* s;    s = (Stack*)malloc(sizeof(Stack));    if (!s) {        printf("空间不足\n");    }    s->next = NULL;    return s;}int IsEmpty(Stack* s) {    return (s->next == NULL);}//入栈void Push(Stack* s, BinaryTree* data) {    Stack* cell;    cell = (Stack*)malloc(sizeof(Stack));    if (!cell) {        printf("空间不足\n");    }    cell->data = data;    cell->next = s->next;    s->next = cell;}//出栈BinaryTree* Pop(Stack* s) {    Stack* firstCell;    BinaryTree* topData;    if (IsEmpty(s)) {        printf("空栈\n");        return NULL;    }    firstCell = s->next;    s->next = firstCell->next;    topData = firstCell->data;    free(firstCell);    return topData;}//创建二叉树节点BinaryTree* CreateBinaryTree(data) {    BinaryTree* t = (BinaryTree*)malloc(sizeof(BinaryTree));    if (!t) {        printf("空间不足!\n");        return NULL;    }    t->lchild = NULL;    t->rchild = NULL;    t->data = data;    return t;}//先序遍历非递归遍历解法void PreOrderTraversal(BinaryTree* BT) {    BinaryTree* T = BT;    Stack* s = CreateStack(); //创建并初始化栈s    while (T || !IsEmpty(s)) {        while (T) { //一直向左并将沿途节点压入栈            Push(s, T);            printf("%c", T->data);            T = T->lchild;        }        if (!IsEmpty(s)) {            T = Pop(s); //节点弹出栈            T = T->rchild; //转向右子树        }    }}//中序遍历非递归遍历解法void InOrderTraversal(BinaryTree* BT) {    BinaryTree* T = BT;    Stack* s = CreateStack(); //创建并初始化栈s    while (T || !IsEmpty(s)) {        while (T) { //一直向左并将沿途节点压入栈            Push(s, T);            T = T->lchild;        }        if (!IsEmpty(s)) {            T = Pop(s); //节点弹出栈            printf("%c", T->data);            T = T->rchild; //转向右子树        }    }}//后序遍历非递归遍历解法void PostOrderTraversal(BinaryTree* BT) {    BinaryTree* T = BT;    Stack* s = CreateStack(); //创建并初始化栈s    while (T || !IsEmpty(s)) {        while (T) { //一直向左并将沿途节点压入栈            T->isFirst = 1;            Push(s, T);            T = T->lchild;        }        if (!IsEmpty(s)) {            T = Pop(s); //节点弹出栈            if(T->isFirst == 1) { //表示是第一次出现在栈顶                T->isFirst = 0;                Push(s, T);                T = T->rchild;            }            else { //第二次出现在栈顶                printf("%c", T->data);                T = NULL;            }        }    }}int main(int argc, const char * argv[]) {    BinaryTree* tree_A = CreateBinaryTree('A');        BinaryTree* tree_B = CreateBinaryTree('B');    tree_A->lchild = tree_B;        BinaryTree* tree_C = CreateBinaryTree('C');    tree_A->rchild = tree_C;        BinaryTree* tree_D = CreateBinaryTree('D');    tree_B->lchild = tree_D;        BinaryTree* tree_F = CreateBinaryTree('F');    tree_B->rchild = tree_F;        BinaryTree* tree_E = CreateBinaryTree('E');    tree_F->lchild = tree_E;        BinaryTree* tree_G = CreateBinaryTree('G');    tree_C->lchild = tree_G;        BinaryTree* tree_I = CreateBinaryTree('I');    tree_C->rchild = tree_I;        BinaryTree* tree_H = CreateBinaryTree('H');    tree_G->rchild = tree_H;        printf("先序遍历非递归遍历算法:");    //先序遍历 => A B D F E C G H I    PreOrderTraversal(tree_A);        printf("\n中序遍历非递归遍历算法:");    //中序遍历 => D B E F A G H C I    InOrderTraversal(tree_A);        printf("\n后序遍历非递归遍历算法:");    //后序遍历 => D E F B H G I C A    PostOrderTraversal(tree_A);        return 0;}



0 0