递归和非递归形式的二叉树前序、中序和后序遍历

建议:先看视频,后复现代码。

/**

* 函数名: 实现二叉树的前序遍历,中序遍历,后序遍历(递归和非递归)

*struct 和 typedef struct的区别:1、C中必须是typedef struct,而C++中都可以。
*                                                       2、C++中,用struct定义的是变量, typedef struct定义的是结构体。

递归视频:https://www.iqiyi.com/v_19rqyv3yes.html#curid=1268584600_4dce78bc839925fcfeba34617bd8b62c
非递归视频:https://www.iqiyi.com/v_19rqyv456k.html

二叉树的非递归实现过程:
      1、将栈顶元素压入栈中
      2、进入循环(判断栈中元素个数是否大于零):
          2、1 弹出栈顶元素
          2、2 如果栈顶元素的标志位为真,则输出栈顶元素,进行下一次的循环
          2、3 如果栈顶元素的标志位为假,将栈顶元素的标志位设为真。
          2、4 将该栈顶元素的右节点、左节点、根节点压入栈中。(非递归的前序遍历,刚好和递归的顺序相反)
               将该栈顶元素的右节点、根节点、左节点压入栈中。(非递归的中序遍历)
               将该栈顶元素的根节点、右节点、左节点压入栈中。(非递归的后序遍历)
          2、5 执行下一次的循环。

待解决问题 : 程序中的非递归前序遍历、中序遍历、后序遍历不能同时运行,没有找到原因
**/

完整代码:


# include <iostream>
# include <stack> 

using namespace std;

struct BinaryNode{  //定义二叉树的节点
    char data; 
    struct BinaryNode*Lchild;   //定义左节点
    struct BinaryNode*Rchild;  //定义右节点
    int flag;                  //定义标志位,出栈标志
};

void preorder_traversal(struct BinaryNode* root) {   //定义右节点
    if (root == NULL) {                              //节点为空,说明是叶节点
        return;
    } 
    printf("%c", root->data);            //先打印根节点
    preorder_traversal(root->Lchild);    //遍历左子树
    preorder_traversal(root->Rchild);     //遍历右子树
}

void inorder_traversal(struct BinaryNode* root) {  //中序遍历
    if (root == NULL) {
        return;
    }
    inorder_traversal(root->Lchild);   //与前序类似,左-根-右
    printf("%c", root->data);
    inorder_traversal(root->Rchild);
}

void postorder_traversal(struct BinaryNode* root) {  //后序遍历
    if (root == NULL) {
        return;
    }
    postorder_traversal(root->Lchild);   //与前序类似,左-右-根
    postorder_traversal(root->Rchild);
    printf("%c", root->data);
}

void non_preorder_traversal(struct BinaryNode* root) {   //非递归前序遍历
    //初始化一个栈
    stack<struct BinaryNode*> s ;
    //取出栈顶元素
    s.push(root);
    struct BinaryNode* p = NULL;
    while (s.size()>0) {
        p = s.top();             //弹出栈顶元素(元素本身还在栈中)
        s.pop();                 //弹出栈顶元素(元素不在栈中)
        if (p->flag == 1) {      //标志为1,打印元素
            printf("%c", p->data);
            continue;              //接着循环
        }
        //将根节点的标志位设成1
        p->flag = 1;
        //将左子树压入栈中
        if (p->Rchild != NULL) {
            s.push(p->Rchild);
        }
        //将右子树压入栈中
        if (p->Lchild != NULL) {
            s.push(p->Lchild);
        }
        //将根节点压入栈中
        s.push(p);
    }
    while (!s.empty())  // 销毁建立的栈
    {
        s.pop();
    }
}

void non_inorder_traversal(struct BinaryNode* root) {   //非递归中序遍历
    stack<struct BinaryNode*> s1;
    s1.push(root);
    struct BinaryNode* p1 = NULL;
    while (s1.size() > 0) {
        p1 = s1.top();  //弹出栈顶元素
        s1.pop();
        if (p1->flag == 1) {
            printf("%c", p1->data);
            continue;
        }
        p1->flag = 1;
        if (p1->Rchild != NULL) {
            s1.push(p1->Rchild);
        }
        s1.push(p1);
        if (p1->Lchild != NULL) {
            s1.push(p1->Lchild);
        }
    }
    while (!s1.empty())  // 销毁建立的栈
    {
        s1.pop();
    }
}

void non_postorder_traversal(struct BinaryNode* root) {   //非递归前序遍历
    stack<struct BinaryNode*> s;
    s.push(root);
    struct BinaryNode* p = NULL;
    while (s.size() > 0) {
        p = s.top();  //弹出栈顶元素
        s.pop();
        if (p->flag == 1) {
            printf("%c", p->data);
            continue;
        }
        p->flag = 1;
        s.push(p);
        if (p->Rchild != NULL) {
            s.push(p->Rchild);
        }
        if (p->Lchild != NULL) {
            s.push(p->Lchild);
        }
    }
    while (!s.empty())  // 销毁建立的栈
    {
        s.pop();
    }
}


int main(void) {
    //定义8个节点
    struct BinaryNode Node1 = { 'A',NULL,NULL, 0 };
    struct BinaryNode Node2 = { 'B',NULL,NULL, 0 };
    struct BinaryNode Node3 = { 'C',NULL,NULL, 0 };
    struct BinaryNode Node4 = { 'D',NULL,NULL, 0 };
    struct BinaryNode Node5 = { 'E',NULL,NULL, 0 };
    struct BinaryNode Node6 = { 'F',NULL,NULL, 0 };
    struct BinaryNode Node7 = { 'G',NULL,NULL, 0 };
    struct BinaryNode Node8 = { 'H',NULL,NULL, 0 };

    //建立结点之间的联系
    Node1.Lchild = &Node2;
    Node1.Rchild = &Node6;
    Node2.Rchild = &Node3;
    Node3.Lchild = &Node4;
    Node3.Rchild = &Node5;
    Node6.Rchild = &Node7;
    Node7.Lchild = &Node8;

    //preorder_traversal(&Node1);  //递归前序遍历
    //printf("\n");
    //printf("__________");
    //printf("\n");

    //inorder_traversal(&Node1);  //递归中序遍历
    //printf("\n");
    //printf("__________");
    //printf("\n");

    //postorder_traversal(&Node1);  //递归后序遍历
    //printf("\n");
    //printf("__________");
    //printf("\n");

    //non_preorder_traversal(&Node1);  //非递归前序遍历
    //printf("\n");
    //printf("__________");
    //printf("\n");

    non_inorder_traversal(&Node1);  //非递归中序遍历
    printf("\n");
    printf("__________");
    printf("\n");

    //non_postorder_traversal(&Node1);  //非递归后序遍历
    //printf("\n");
    //printf("__________");
    //printf("\n");

    system("PAUSE");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值