二叉树的三种遍历(递归与非递归)

创建一个二叉树

从键盘先序扩展一个二叉树

typedef struct Node {
    char data;
    struct Node *Lchild;
    struct Node *Rchild;
}BiTNode, * BiTree;
int lengthOfTree = 0;
BiTree init() {
    char s = '#';
    scanf("%c", &s);
    lengthOfTree++;
    BiTree tree;
//    ABC##DE#G##F###
    if (s == '#') {
        tree = NULL;
    } else if (s == ' ') {
        tree = NULL;
    } else{
        tree = (BiTree)malloc(sizeof(BiTNode));
        tree->data = s;
        tree->Lchild = init();
        tree->Rchild = init();
    }
    return tree;
}
int main(void) {
    BiTree root = (BiTree)malloc(sizeof(BiTNode));
    root = init();
    return 0;
}

先序遍历

递归

先访问跟节点
然后左子树
然后右子树

void PreOrder(BiTree root) {
    if (root) {
        printf("%c", root->data);
        PreOrder(root->Lchild);
        PreOrder(root->Rchild);
    }
}

非递归

按照先序的思想,可以转化为循环控制。


1入栈。
1出栈(栈顶元素出栈),输出栈顶元素1,并将1的左右孩子节点入栈;其中右孩子4先入栈,然后左孩子2入栈。(因为,对左边孩子的访问先序遍历先于右孩子,后入栈的先访问)。
2出栈(栈顶元素出栈),输出栈顶元素2,并将2的左右孩子节点入栈,同理5先入栈,3后入栈。
3出栈(栈顶元素出栈),输出栈顶元素3,3为叶子结点,无孩子,本次无入栈。
5出栈(栈顶元素出栈),输出栈顶元素5
4出栈(最后的栈顶元素出栈),此时 栈空,遍历完毕。
void PreOrderAnother(BiTree root) {
BiTNode *s[100] = {0};
int top = 0;
s[top++] = root;
while(top > 0) {
root = s[–top];
printf("%c", root->data);
if (root->Rchild){
s[top++] = root->Rchild;
}
if (root->Lchild) {
s[top++] = root->Lchild;
}
}
}

中序

递归

先访问左子树,左子树访问完访问双亲,然后访问右子树
void inOrder(BiTree root) {
if (root) {
inOrder(root->Lchild);
printf("%c", root->data);
inOrder(root->Rchild);
}
}

非递归

中序遍历是先便利左子树,所以要从任何一个节点开始,都要找左子树,直到为叶子结点,然后再访问

void InorderAnother(BiTree root) {
    BiTree s[100] = {0};
    int top = 0;
    s[top++] = root;
    if (root->Lchild) {
        root = root->Lchild;
    } else {
        printf("%c", root->data);
        root = root->Rchild;
    }
    while (root ||top > 0) {
        while(root) {
            s[top++] = root;
            root = root->Lchild;
        }
            root = s[--top];
            printf("%c", root->data);
            root = root->Rchild;
    }
}

后续

递归

先访问左子树,再访问右子树,最后访问双亲

void PostOrder(BiTree root) {
    if (root) {
        PostOrder(root->Lchild);
        PostOrder(root->Rchild);
        printf("%c", root->data);
    }
}

非递归

我太菜了,还没有写出来

找叶子结点,一度节点,二度节点

代码很好懂

int leafv = 0, one = 0, two = 0;
char leaves[100];
void FindLeavies(BiTree root) {
    if (root) {
        if (!(root->Lchild) && !(root->Rchild)) {
            leaves[leafv] = root->data;
            leafv++;
            return;
        } else if (!(root->Lchild) || !(root->Rchild)) {
            one++;
        }
        if (root->Lchild && root->Rchild) {
            two++;
        }
        FindLeavies(root->Lchild);
        FindLeavies(root->Rchild);
    }
}

你可能感兴趣的:(二叉树的三种遍历(递归与非递归))