二叉树的建立与基本操作(北理工数据结构与算法设计题目)题解

编写程序实现二叉树的如下操作:
1) 建立二叉链表
2) 二叉树的先序、中序、后序遍历
3) 求二叉树的叶子结点个数
4) 将二叉树中所有结点的左、右子树相互交换

输入:
  扩展二叉树先序序列:ab#d##ce###。其中#代表空指针。

输出:
  二叉树的凹入表示
  二叉树的先序序列、中序序列、后序序列
  二叉树叶子结点个数
  左、右子树相互交换后的二叉树的凹入表示
  左、右子树相互交换后的二叉树的先序序列、中序序列、后序序列。

说明:
  在输出凹入表示的二叉树时,先输出根结点,然后依次输出左右子树,上下层结点之间相隔 3 个空格。

代码如下,请勿完全复制粘贴

// By Zhang Xiangnan, School of Future Technologies, 2024.11.21

#include <iostream>
#include <string>
#include <memory>

typedef struct Node
{
    char data;
    std::unique_ptr<struct Node> left_child;
    std::unique_ptr<struct Node> right_child;
} Node;

enum TraverseType {DLR, LDR, LRD};

class BiTree
{
    std::unique_ptr<Node> root_ptr;
    
    void node_create(std::unique_ptr<Node> &nodeptr_ref, const std::string &sequence, int &idx_ref)
    {
        if(idx_ref >= sequence.size()) return;
        const char element = sequence[idx_ref++];
        if(element == '#')
        {
            nodeptr_ref.reset(nullptr);
            return;
        }
        nodeptr_ref.reset(new Node);
        nodeptr_ref->data = element;
        node_create(nodeptr_ref->left_child, sequence, idx_ref);
        node_create(nodeptr_ref->right_child, sequence, idx_ref);
    }

    void node_print(const std::unique_ptr<Node> &nodeptr_ref, int print_place) const
    {
        if(nodeptr_ref == nullptr) return;
        int i = 1;
        for(i=1; i<=print_place-1; i++) std::cout << ' ';
        std::cout << nodeptr_ref->data << std::endl;
        node_print(nodeptr_ref->left_child, print_place+4);
        node_print(nodeptr_ref->right_child, print_place+4);
    }

    void node_traverse(std::unique_ptr<Node> const &nodeptr_ref, std::string &sequence_ref, TraverseType type) const
    {
        if(nodeptr_ref == nullptr) return;
        if(type == TraverseType::DLR)
            sequence_ref.push_back(nodeptr_ref->data);
        node_traverse(nodeptr_ref->left_child, sequence_ref, type);
        if(type == TraverseType::LDR)
            sequence_ref.push_back(nodeptr_ref->data);
        node_traverse(nodeptr_ref->right_child, sequence_ref, type);
        if(type == TraverseType::LRD)
            sequence_ref.push_back(nodeptr_ref->data);
    }

    int node_leafnum(std::unique_ptr<Node> const &nodeptr_ref) const
    {
        if(nodeptr_ref == nullptr) return 0;
        else if(nodeptr_ref->left_child == nullptr and nodeptr_ref->right_child == nullptr) return 1;
        else
            return node_leafnum(nodeptr_ref->left_child) + node_leafnum(nodeptr_ref->right_child);
    }

    void node_swap(std::unique_ptr<Node> &nodeptr_ref)
    {
        if(nodeptr_ref == nullptr) return;
        node_swap(nodeptr_ref->left_child);
        node_swap(nodeptr_ref->right_child);
        std::unique_ptr<Node> temp = std::move(nodeptr_ref->left_child);
        nodeptr_ref->left_child = std::move(nodeptr_ref->right_child);
        nodeptr_ref->right_child = std::move(temp);
    }

public:

    BiTree(const std::string &sequence)
    {
        int idx = 0;
        node_create(root_ptr, sequence, idx);
    }

    void print() const
    {
        node_print(root_ptr, 1);
    }

// By Zhang Xiangnan, School of Future Technologies, 2024.11.21

    std::string traverse(TraverseType type) const
    {
        std::string sequence;
        node_traverse(root_ptr, sequence, type);
        return sequence;
    }

    int get_leafnum() const
    {
        return node_leafnum(root_ptr);
    }

    void swap()
    {
        node_swap(root_ptr);
    }

};

inline void show_tree(const BiTree &tree)
{
    tree.print();
    std::cout << "pre_sequence  : " << tree.traverse(TraverseType::DLR) << std::endl;
    std::cout << "in_sequence   : " << tree.traverse(TraverseType::LDR) << std::endl;
    std::cout << "post_sequence : " << tree.traverse(TraverseType::LRD) << std::endl;
}


int main(void)
{
    std::string sequence;
    std::getline(std::cin, sequence);
    BiTree tree(sequence);
    std::cout << "BiTree" << std::endl;

    show_tree(tree);
    std::cout << "Number of leaf: " << tree.get_leafnum() << std::endl;
    tree.swap();
    std::cout << "BiTree swapped" << std::endl;
    show_tree(tree);

    return 0;
}

// By Zhang Xiangnan, School of Future Technologies, 2024.11.21

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

张向南zhangxn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值