2018.5.19(二叉树的遍历-递归(系统压栈))

二叉树前根序、中根序、后根序遍历分析

借鉴大神博客
https://blog.csdn.net/prince_jun/article/details/7699024

1数组表示二叉树

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int tree[1<<20];//用位运算,1<<20相当于2^20;
int N;
int cur;

void print_01(int index)//调用递归输出,前序遍历
{
    if(cur>N)
        return ;
    if(tree[index]==0)
        return ;

    printf("%d ",tree[index]);
    cur++;

    print_01(index*2);//判断左子树的语句在前,递归时优先判断是否存在符合条件的左子树;
    print_01(index*2+1);
}

void print_02(int index)//中序遍历
{
    if(cur>N)
        return ;
    if(tree[index]==0)
        return ;

    print_02(index*2);

    printf("%d ",tree[index]);
    cur++;

    print_02(index*2+1);
}

void print_03(int index)//后序遍历
{
    if(cur>N)
        return ;
    if(tree[index]==0)
        return ;

    print_03(index*2);
    print_03(index*2+1);

    printf("%d ",tree[index]);
    cur++;
}

int main()
{
    while(cin>>N)
    {
        int node[N+1];

        memset(tree,0,sizeof(tree));

        for(int i=1;i<=N;i++)
            cin>>node[i];

        for(int i=1;i<=N;i++)//二叉查找树的建立
        {
            if(i==1)
            {
                tree[1]=node[i];
                continue;
            }

            int index=1;
            while(tree[index]!=0)
                index=(node[i]>tree[index])?(2*index+1):(2*index);
            tree[index]=node[i];
        }

        cur=1;
        printf("前序遍历\n");
        print_01(1);
        printf("\n");

        cur=1;
        printf("中序遍历\n");
        print_02(1);
        printf("\n");

        cur=1;
        printf("后序遍历\n");
        print_03(1);
        printf("\n");
    }
    return 0;
}
//  调用递归输出前序、中序、后序遍历解析

void print_01(int index)//调用递归输出,前序遍历
{
    if(cur>N)
        return ;
    if(tree[index]==0)
        return ;

    printf("%d ",tree[index]);
    cur++;

    print_01(index*2);//判断左子树的语句在前,递归时优先判断是否存在符合条件的左子树;
    print_01(index*2+1);
}

假设一棵树有九个节点,分别为6,3,8,5,2,9,4,7,10;
用树状结构表示为:
这里写图片描述
先不考虑打印语句,只看 print_01(index*2);print_01(index*2+1);这两个语句,起初,index指向数据6位置,先执行 print_01(index*2),来到数据3位置,在执行 print_01(index*2),来到数据2位置,在执行 print_01(index*2)发现数据2无左孩子,系统返回到数据2位置,在执行print_01(index*2+1),发现数据2无右孩子,系统接着返回到数据2位置,此时系统压栈的数据为6,3,2,2,2接着往上回溯,来到数据3位置,执行print_01(index*2+1),来到数据5位置,执行 print_01(index*2)语句来到数据4位置,在数据4位置执行 print_01(index*2)发现数据4无左孩子,系统返回到数据4位置,在执行print_01(index*2+1),发现数据4无右孩子,系统接着返回到数据4位置,此时系统压栈数据为6,3,2,2,2,3,5,4,4,4,系统接着上述操作由数据4位置返回到数据5位置,依次类推,总的压栈数据为6,3,2,2,2,3,5,4,4,4,5,5,3,6,8,7,7,7,8,9,9,10,10,10,9,8,6
而前序遍历,是先便利根节点,再依次遍历左子树和右子树,即按节点先便利的先输出,故printf()打印函数放在了print_01(index*2)和print_01(index*2+1)之前(632,2,2,3,54,4,4,5,5,3,6,87,7,7,8,9,9,10,10,10,9,8,6);
即打印出6,3,2,5,4,8,7,9,10;
同理,根据中序遍历的规则,是先打印左子树,在打印根节点,在打印右子树,即某一结点在第二次遍历时才打印,故printf()语句放在两个print_01()语句间(6,3,2,2,2,3,5,4,4,4,5,5,3,6,8,7,7,7,8,9,9,10,10,10,9,8,6)
即打印出2,3,4,5,6,7,8,9,10;
同理,后序遍历某一节点第三次遍历时才打印,printf()语句放在两个print_01()语句后(6,3,2,2,2,3,5,4,4,4,5,53,6,8,7,7,7,8,9,9,10,10,10986);
即打印出2,4,5,3,7,10,9,8,6;

2链表表示二叉树

#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;

struct Tree
{
    Tree *left;
    Tree *right;
    int data;
    Tree *next;
};

Tree *Insert(Tree *root,int node)
{
    Tree *new_node,*parent_node,*current_node;

    new_node=(Tree*)malloc(sizeof(Tree));
    new_node->data=node;
    new_node->left=NULL;
    new_node->right=NULL;

    if(root==NULL)
        return new_node;

    current_node=root;
    while(current_node!=NULL)
    {
        parent_node=current_node;
        current_node=(node>current_node->data)?(current_node->right):(current_node->left);
    }

    if(node>parent_node->data)
        parent_node->right=new_node;
    else
        parent_node->left=new_node;
    //(node>parent_node->data)?(parent_node->right):(parent_node->left)=new_node;(此语句有误)

    return root;
}

Tree *Create(int *node,int len)
{
    Tree *root=NULL;

    for(int i=1;i<=len;i++)
        root=Insert(root,node[i]);

    return root;
}

void print_01(Tree *root)//前序遍历;
{
    if(root!=NULL)
    {
        printf("%d ",root->data);
        print_01(root->left);
        print_01(root->right);
    }
}

void print_02(Tree *root)//中序遍历;
{
    if(root!=NULL)
    {
        print_02(root->left);
        printf("%d ",root->data);
        print_02(root->right);
    }
}

void print_03(Tree *root)//后序遍历;
{
    if(root!=NULL)
    {
        print_03(root->left);
        print_03(root->right);
        printf("%d ",root->data);
    }
}

int main()
{
    int N;

    while(cin>>N)
    {
        Tree *root=NULL;
        int node[N+1];
        for(int i=1;i<=N;i++)
            cin>>node[i];

        root=Create(node,N);

        printf("***前序遍历***\n");
        print_01(root);
        printf("\n");

        printf("***中序遍历***\n");
        print_02(root);
        printf("\n");

        printf("***后序遍历***\n");
        print_03(root);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Violet_ljp/article/details/80378033