C++版二叉树的创建与遍历

使用补空法创建了一棵二叉树,并且实现了先序遍历、中序遍历、后序遍历、层次遍历功能。

1、定义结点类:

要创建二叉树首先要定义二叉树的结点类,二叉树上每一个结点有3个成员变量,一个存放当前结点的值,其余两个是指针类型,分别指向此节点的左孩子和右孩子;

class Node
{
public:
    char data;
    Node* lchild;   //指向左孩子
    Node* rchild;   //指向右孩子
};

using Tree = Node*;  

2、使用补空法创建二叉树

补空法是指:如果结点没有孩子,在写遍历序列时,在其孩子的位置补‘#’(也可是别的有特殊定义的字符)。

使用先序序列创建二叉树时,先判断字符是否为'#':如果是,说明此处没有结点,指针空指;如果不是,说明有结点,先动态创建一个新结点,给数据域赋值,然后递归创建左子树、递归创建右子树。

void CreateTree(Tree& t)
{
    char c;
    cin >> c;
    if (c == '#')
    {
        t = nullptr;    //没有结点就空指
    }
    else     //创建新结点
    {
        t = new Node;
        t->data = c;
        CreateTree(t->lchild);
        CreateTree(t->rchild);
    }
}

3、先序遍历

非常简单,分为三步:打印当前结点数据、递归左孩子、递归右孩子(根左右)

递归前要确保左|右孩子存在(左|右孩子的指针不空)

void DLR(const Tree& t)
{
    cout << t->data << " ";
    if (t->lchild)
    {
        DLR(t->lchild);
    }
    if (t->rchild)
    {
        DLR(t->rchild);
    }
}

4、中序遍历

(左根右)

void LDR(const Tree& t)
{
    if (t->lchild)
    {
        LDR(t->lchild);
    }
    cout << t->data << " ";
    if (t->rchild)
    {
        LDR(t->rchild);
    }
}

5、后序遍历

(左右根)

void LRD(const Tree& t)
{
    if (t->lchild)
    {
        LRD(t->lchild);
    }
    if (t->rchild)
    {
        LRD(t->rchild);
    }
    cout << t->data << " ";
}

6、层次遍历

层次遍历是从根开始按照辈分大小向下逐层输出,具有先来先服务特性,适合用队列

队列里存的是指向各个结点的指针,先把根节点的指针放进队列;若队列不空,取走并打印队头结点,然后此结点的左右孩子入队,循环遍历即可。

void Gradation(const Tree& t)
{
    queue<Node*> q;   //存的是指针不是结点
    q.push(t);    //先把树根的指针入队
    Node* temp = nullptr;
    while (!q.empty())
    {
        temp = q.front();
        q.pop();
        cout << temp->data << " ";
        if (temp->lchild)
        {
            q.push(temp->lchild);
        }
        if (temp->rchild)
        {
            q.push(temp->rchild);
        }
    }
}

总体代码实现:

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

class Node
{
public:
    char data;
    Node* lchild;   //指向左孩子
    Node* rchild;   //指向右孩子
};

using Tree = Node*;    

void CreateTree(Tree& t)
{
    char c;
    cin >> c;
    if (c == '#')
    {
        t = nullptr;    //没有结点就空指
    }
    else     //创建新结点
    {
        t = new Node;
        t->data = c;
        CreateTree(t->lchild);
        CreateTree(t->rchild);
    }
}

//先序遍历
void DLR(const Tree& t)
{
    cout << t->data << " ";
    if (t->lchild)
    {
        DLR(t->lchild);
    }
    if (t->rchild)
    {
        DLR(t->rchild);
    }
}

//中序遍历
void LDR(const Tree& t)
{
    if (t->lchild)
    {
        LDR(t->lchild);
    }
    cout << t->data << " ";
    if (t->rchild)
    {
        LDR(t->rchild);
    }
}

//后序遍历
void LRD(const Tree& t)
{
    if (t->lchild)
    {
        LRD(t->lchild);
    }
    if (t->rchild)
    {
        LRD(t->rchild);
    }
    cout << t->data << " ";
}

//层次遍历
void Gradation(const Tree& t)
{
    queue<Node*> q;   //存的是指针不是结点
    q.push(t);    //先把树根的指针入队
    Node* temp = nullptr;
    while (!q.empty())
    {
        temp = q.front();
        q.pop();
        cout << temp->data << " ";
        if (temp->lchild)
        {
            q.push(temp->lchild);
        }
        if (temp->rchild)
        {
            q.push(temp->rchild);
        }
    }

}

int main()
{
    Tree my_tree;
    int choose = 0;
    cout << "请选择要执行的操作" << endl;
    cout << "1、创建二叉树" << endl;
    cout << "2、先序遍历" << endl;
    cout << "3、中序遍历" << endl;
    cout << "4、后序遍历" << endl;
    cout << "5、层次遍历" << endl;
    cout << "0、退出" << endl;
    while (cin >> choose)
    {
        switch (choose)
        {
        case 1:
            cout << "请输入要创建树的先序序列,结点没有孩子的位置用#代替:" << endl;
            CreateTree(my_tree);
            cout << endl;
            break;
        case 2:
            cout << "先序遍历:" << endl;
            DLR(my_tree);
            cout << endl;
            break;
        case 3:
            cout << "中序遍历:" << endl;
            LDR(my_tree);
            cout << endl;
            break;
        case 4:
            cout << "后序遍历:" << endl;
            LRD(my_tree);
            cout << endl;
            break;
        case 5:
            cout << "层次遍历:" << endl;
            Gradation(my_tree);
            cout << endl;
            break;
        case 0:
            cout << "Bye-Bye" << endl;
            return 0;
        default:
            break;
        }
        cout << "请输入下一个指令" << endl;
    }
    return 0;
}

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可惜浅灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值