二叉树之前序/中序/后序和层次遍历


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

typedef struct TreeNode{
    char data;
    TreeNode* left;
    TreeNode* right;
} TreeNode;

#define STR_SIZE 1024


//创建二叉树
int createBTNode(TreeNode** BT, char* str, int n) {
    char ch = str[n++];  // 把第 n 个字符赋给ch,方便后面判断,字符下标后移
    if (ch != '\0') {    // 如果 ch 不等于结束符就继续创建,否则就结束
        if (ch == '#') { // 以 # 号代表 NULL,下面没有了
            *BT = NULL;
        } else {
            if (!(*BT = (TreeNode*)malloc(sizeof(TreeNode)))) {
                printf("内存分配失败!");
                exit(-1);
            } else {
                (*BT)->data = ch;
                n = createBTNode(&((*BT)->left), str, n); // 左递归创建
                n = createBTNode(&((*BT)->right), str, n); // 右递归创建
            }
        }
    }
    // 返回 n,记录字符串使用到哪里了
    return n;
}
//前序遍历
void preOrder(TreeNode* bt)
{
    if(bt!=NULL)
    {
        printf("%c->",bt->data);
        preOrder(bt->left);
        preOrder(bt->right);
    }
}
//中序遍历
void inOrder(TreeNode* bt)
{
    if(bt!=NULL)
    {
        inOrder(bt->left);
        printf("%c->",bt->data);
        inOrder(bt->right);
    }
}
//后序遍历
void postOrder(TreeNode* bt)
{
    if(bt!=NULL)
    {
        postOrder(bt->left);
        postOrder(bt->right);
        printf("%c->",bt->data);
    }
}

//层次遍历
//https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-xu-bian-li-by-leetcode-solution/
void levelOrder(TreeNode* bt) {
    queue<TreeNode*> q;
    TreeNode* root=bt;
    if(root!=NULL)
    {
        q.push(bt);//根节点入队列
    }
    while(!q.empty())
    {
        int currentLevelSize=q.size();
        for(int i=0;i<currentLevelSize;i++)
        {
            //出队列
            TreeNode* node=q.front();
            printf("%c->",node->data);
            q.pop();
            if(node->left!=NULL)
            {
                q.push(node->left);
            }
            if(node->right!=NULL)
            {
                q.push(node->right);
            }
        }
    }
}

void levelOrder_getFirst(TreeNode* bt) {
    queue<TreeNode*> q;
    TreeNode* root=bt;
    if(root!=NULL)
    {
        q.push(bt);//根节点入队列
    }
    while(!q.empty())
    {
        int currentLevelSize=q.size();//每一个层
        for(int i=0;i<currentLevelSize;i++)
        {
            //出队列
            TreeNode* node=q.front();
            if(i == 0)
            {
                printf("%c->",node->data);
            }
            q.pop();
            if(node->left!=NULL)
            {
                q.push(node->left);
            }
            if(node->right!=NULL)
            {
                q.push(node->right);
            }
        }
    }
}


/*****************************************************************************
* @date   2020/4/19
* @brief  水平画树
* @param  node	二叉树节点
* @param  left	判断左右
* @param  str 	可变字符串
*****************************************************************************/
void draw_level(TreeNode* root, bool left, char* str) {
    TreeNode* node=root;
    if (node->right) {
        draw_level(node->right, false, strcat(str, (left ? "|     " : "      ")));
    }

    printf("%s", str);
    printf("%c", (left ? '\\' : '/'));
    printf("-----");
    printf("%c\n", node->data);

    if (node->left) {
        draw_level(node->left, true, strcat(str, (left ? "      " : "|     ")));
    }
    //  "      " : "|     " 长度为 6
    str[strlen(str) - 6] = '\0';
    fflush(stdout); //清空输出流
}

/*****************************************************************************
* @date   2020/4/19
* @brief  根节点画树
* @param  root	二叉树根节点
*****************************************************************************/
void draw(TreeNode* BT) {
    char str[STR_SIZE];
    memset(str, '\0', STR_SIZE);
    TreeNode* root_left=BT;
    TreeNode* root_right=BT;

    /**
     * 1. 在 windows 下,下面是可执行的
     * 2. 在 Linux   下,执行会报 Segmentation fault
     *      需要使用中间变量
     */
    if (root_right->right) {
        draw_level(root_right->right, false, str);
    }
    if(BT!=NULL)
    {
        printf("%c\n", BT->data);
    }
    if (root_left->left) {
        draw_level(root_left->left, true, str);
    }
}

//https://blog.csdn.net/weixin_42109012/article/details/92250160
int main()
{
    // 例子: ABDH###E##CF##G##
    //AB#D#E##CF##G##
    //AB#D#E##CF##G#HI####
    TreeNode* BT;
    printf("请输入字符串:");
    char* str = (char*)malloc(sizeof(char) * STR_SIZE);
    scanf("%s", str);
    if (strlen(str) == createBTNode(&BT, str, 0)) {
        printf("二叉树建立成功\n");
    }
    draw(BT);

    printf("\n先序遍历结果:");
    preOrder(BT);

    printf("\n中序遍历结果:");
    inOrder(BT);

    printf("\n后序遍历结果:");
    postOrder(BT);

    printf("\n层序遍历结果:");
    levelOrder(BT);

    printf("\n定制层序遍历结果:");
    levelOrder_getFirst(BT);

    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值