二叉树的建立和递归遍历、非递归遍历操作

 
 

二叉树是我们平时使用较多的一种数据结构,它是每个节点最多有两个子树的树结构。关于树的概念和性质就不再多介绍,我来对数的建立和一些操作进行总结。

首先我们定义树的数据类型:

typedef struct TREE_NODE
{
    char data;
    struct TREE_NODE *lchild;
    struct TREE_NODE *rchild;
}*tree_node;
树有一个数据域和两个指针域,采用的是链式存储结构;

我们定义一个tree_node t之后我们首先要创建并输入一个树:

tree_node createTree()   //树的建立
{
    char ch;
    tree_node t;
    ch=getchar();  //输入二叉树数据
    if(ch=='#')  //判断二叉树是否为空
        t=NULL;
    else
    {
        t=(tree_node)malloc(sizeof(tree_node));  //二叉树的生成
        t->data=ch;
        t->lchild=createTree();
        t->rchild=createTree();
    }
    return t;
}
在输入树的过程中,我们需要输入符号来判断这个树的节点到这里是否停止了,所以有一个判断if(ch=='#');

这样我们便建立好一个树了,并且输入了数据,我们对数最基本也是重要的操作当然就是遍历,对于树的遍历我们有三种方式,分别是前序遍历,中序遍历,后序遍历,我们先看看递归遍历的方法:

void preOrder(tree_node t)  //先序遍历
{
    if(t)
    {
        printf("%c",t->data);
        preOrder(t->lchild);
        preOrder(t->rchild);
    }
}

void intOrder(tree_node t)  //中序遍历
{
    if(t)
    {
        intOrder(t->lchild);
        printf("%c",t->data);
        intOrder(t->rchild);
    }
}
void preOrder(tree_node t)  //先序遍历
{
    if(t)
    {
        printf("%c",t->data);
        preOrder(t->lchild);
        preOrder(t->rchild);
    }
}
这是我们用递归的方式对树进行的遍历,若我们不采用递归的方式,我们如何进行遍历:

void preOrder(tree_node t) //前序遍历
{
    stack<tree_node> s;
    tree_node p = t;
    while(p!=NULL || !s.empty())
    {
        while(p!=NULL)
        {
            cout << p->data;
            s.push(p);
            p = p->lchild;
        }
        if(!s.empty())
        {
            p = s.top();
            s.pop();
            p = p->rchild;
        }
    }
}
void intOrder(tree_node t) //中序遍历
{
    stack<tree_node> s;
    tree_node p = t;
    while(p!= NULL || !s.empty())
    {
        while(p!=NULL)
        {
            s.push(p);
            p = p->lchild;
        }
        if(!s.empty())
        {
            p = s.top();
            cout << p->data;
            s.pop();
            p = p->rchild;
        }
    }
}

typedef struct node1
{
    TREE_NODE *btnode;
    bool isFirst;
}*BTNode;
void postOrder(tree_node t) //后序遍历
{
    stack<BTNode> s;
    tree_node p = t;
    BTNode q;
    while(p!=NULL || !s.empty())
    {
        while(p!=NULL)
        {
            BTNode bt = (BTNode)malloc(sizeof(BTNode));
            bt->btnode = p;
            bt->isFirst = true;
            s.push(bt);
            p = p->lchild;
        }
        if(!s.empty())
        {
            q = s.top();
            s.pop();
            if(q->isFirst ==true)
            {
                q->isFirst = false;
                s.push(q);
                p = q->btnode->rchild;
            }
            else
            {
                cout << q->btnode->data;
                p = NULL;
            }
        }
    }
}

非递归的的后序遍历比较麻烦,需要我们沿着左子树一直向下搜索,直到没有左子树的时候,我们此时不能出栈访问,我们还需讲右子树入栈,我们把右子树做了相同处理之后,我们才可以出栈访问,这样我们就需要多设置一个标识每个节点第几次到达栈顶,只有第二次到达栈顶的时候我们才可以出栈访问。

完整的代码如下:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<stack>
using namespace std;
typedef struct TREE_NODE
{
    char data;
    struct TREE_NODE *lchild;
    struct TREE_NODE *rchild;
}*tree_node;
typedef struct node1
{
    TREE_NODE *btnode;
    bool isFirst;
}*BTNode;
tree_node createTree()   //树的建立
{
    char ch;
    tree_node t;
    ch=getchar();  //输入二叉树数据
    if(ch=='#')  //判断二叉树是否为空
        t=NULL;
    else
    {
        t=(tree_node)malloc(sizeof(tree_node));  //二叉树的生成
        t->data=ch;
        t->lchild=createTree();
        t->rchild=createTree();
    }
    return t;
}

void preOrder(tree_node t)  //先序遍历
{
    if(t)
    {
        printf("%c",t->data);
        preOrder(t->lchild);
        preOrder(t->rchild);
    }
}
//void preOrder(tree_node t) //先序遍历
//{
//    stack<tree_node> s;
//    tree_node p = t;
//    while(p!=NULL || !s.empty())
//    {
//        while(p!=NULL)
//        {
//            cout << p->data;
//            s.push(p);
//            p = p->lchild;
//        }
//        if(!s.empty())
//        {
//            p = s.top();
//            s.pop();
//            p = p->rchild;
//        }
//    }
//}
void intOrder(tree_node t)  //中序遍历
{
    if(t)
    {
        intOrder(t->lchild);
        printf("%c",t->data);
        intOrder(t->rchild);
    }
}
//void intOrder(tree_node t) //中序遍历
//{
//    stack<tree_node> s;
//    tree_node p = t;
//    while(p!= NULL || !s.empty())
//    {
//        while(p!=NULL)
//        {
//            s.push(p);
//            p = p->lchild;
//        }
//        if(!s.empty())
//        {
//            p = s.top();
//            cout << p->data;
//            s.pop();
//            p = p->rchild;
//        }
//    }
//}
void postOrder(tree_node t)  //后序遍历
{
    if(t)
    {
        postOrder(t->lchild);
        postOrder(t->rchild);
        printf("%c",t->data);
    }
}
//void postOrder(tree_node t) //后序遍历
//{
//    stack<BTNode> s;
//    tree_node p = t;
//    BTNode q;
//    while(p!=NULL || !s.empty())
//    {
//        while(p!=NULL)
//        {
//            BTNode bt = (BTNode)malloc(sizeof(BTNode));
//            bt->btnode = p;
//            bt->isFirst = true;
//            s.push(bt);
//            p = p->lchild;
//        }
//        if(!s.empty())
//        {
//            q = s.top();
//            s.pop();
//            if(q->isFirst ==true)
//            {
//                q->isFirst = false;
//                s.push(q);
//                p = q->btnode->rchild;
//            }
//            else
//            {
//                cout << q->btnode->data;
//                p = NULL;
//            }
//        }
//    }
//}
int main()
{
    int num[10]= {0};
    int height;
    int i,a=0;
    tree_node t;
    t=createTree();
    printf("前序遍历:");
    preOrder(t) ;
    printf("\n");
    printf("中序遍历:");
    intOrder(t);
    printf("\n");
    printf("后序遍历:");
    postOrder(t);
    printf("\n");
}





你可能感兴趣的:(数据结构,递归,二叉树,遍历,非递归)