【二叉树算法题记录】创建与遍历

本文详细介绍了如何在C++中使用结构体和类实现二叉树,包括生物树的定义、三种构造函数,以及前序、中序和后序遍历的递归和迭代方法。
摘要由CSDN通过智能技术生成

tree.h

#include <iostream>
#include <stack>
#ifndef _TREE
#define _TREE

using namespace std;

struct bioTree {
    char val; // 节点的值
    bioTree *left, * right;  // 节点的左子树,右子树

    // 三种构造函数(应对用户的不同输入)
    bioTree() : val('#'), left(nullptr), right(nullptr) {}
    bioTree(char x) : val(x), left(nullptr), right(nullptr) {}
    bioTree(char x, bioTree* left, bioTree* right) : val(x), left(left), right(right) {}
};

class Tree{
private:

public:
    void CreateTree(bioTree **T) {
        char ch;
        cin >> ch;
        if (ch == '#') {    // 如果输入是#,说明当前节点为空
            *T = NULL;
            //return; // 并且要跳回上一层
        }
        else {
            *T = (bioTree *)malloc(sizeof(bioTree));
            (*T)->val = ch;
            CreateTree(&((*T)->left));
            CreateTree(&((*T)->right));
        }

    }

    // 递归:前序遍历
    void PreOrderTrav(bioTree* T){
        if (T == NULL) {    // 判断T是否为空树
            return;
        }
        cout << T->val << " ";  // 输出中间节点的值
        PreOrderTrav(T->left);  // 遍历左子树
        PreOrderTrav(T->right); // 遍历右子树
    }

    // 递归:中序遍历
    void InOrderTrav(bioTree* T) {
        if (T == NULL) {    // 判断T是否为空树
            return;
        }
        InOrderTrav(T->left);  // 遍历左子树
        cout << T->val << " ";  // 输出中间节点的值
        InOrderTrav(T->right); // 遍历右子树
    }

    // 递归:后序遍历
    void PostOrderTrav(bioTree* T) {
        if (T == NULL) {    // 判断T是否为空树
            return;
        }
        PostOrderTrav(T->left);  // 遍历左子树
        PostOrderTrav(T->right); // 遍历右子树
        cout << T->val << " ";  // 输出中间节点的值
    }

    // 迭代:前序遍历
    void IterPreOrderTrav(bioTree* T) {
        stack<bioTree*> s;  // 创建一个栈来存放树节点
        if (T == NULL) return;  // 如果是空树,就直接返回
        s.push(T);  // 先把根节点放进栈
        while (!s.empty()) {    // 栈空即遍历完
            bioTree* node = s.top();    // 获取栈顶元素并让他出栈(中间节点)
            s.pop();
            cout << node->val << "  ";  // 输出中间节点
            if (node->right) s.push(node->right);   // 如果它有右孩子,先让右孩子入栈(前序遍历左孩子先出)
            if (node->left) s.push(node->left); // 如果它有左孩子,再让左孩子入栈
        }
    }

    // 迭代:中序遍历
    void IterInOrderTrav(bioTree* T) {
        stack<bioTree*> s;
        bioTree* cur = T;   // 用指针来访问节点
        while (cur != NULL || !s.empty()) {
            if (cur != NULL) {
                s.push(cur);    // 将访问的节点放进栈
                cur = cur->left;    // 左
            }
            else {
                cur = s.top();  // 弹出栈顶元素
                s.pop();
                cout << cur->val << "   ";   // 中
                cur = cur->right;    // 右
            }
        }
    }

    // 迭代:后序遍历
    // 统一写法,将访问节点放入栈中,把要处理的节点也放入栈中,紧接着一个空指针作为标记
    void IterPostOrderTrav(bioTree* T){
        stack<bioTree*> s;  // 创建一个栈来存放树节点
        if (T != NULL) s.push(T);   // 如果不是空树,就把根节点放进栈
        while (!s.empty()) {
            bioTree* node = s.top();    // 取s的堆顶节点
            if (node != NULL) { // 如果栈顶不是空节点,说明不是要处理节点
                s.pop();    // 让该节点弹出,避免重复操作,    
                s.push(node);   // 添加中节点
                s.push(NULL);   // 中节点访问过,但是还没有处理,加入空节点做为标记。

                if (node->right) s.push(node->right);   // 添加右节点
                if (node->left) s.push(node->left); // 添加左节点
            }
            else {  // 遇到空节点时,才将下一个节点放进结果集
                s.pop();
                node = s.top();
                s.pop();
                cout << node->val << "  ";
            }
        }
    }
};

#endif // !TREE

tree.cpp

#include "tree.h"

int main()
{
    Tree tree;  // 创建一个树
    bioTree *T;   // T是树的根节点

    tree.CreateTree(&T);
    
    cout << "PreOrderTrav: ";
    tree.PreOrderTrav(T);
    cout << endl;
    
    cout << "InOrderTrav: ";
    tree.InOrderTrav(T);
    cout << endl;
    
    cout << "PostOrderTrav: ";
    tree.PostOrderTrav(T);
    cout << endl;

    cout << "IterPreorderTrav: ";
    tree.IterPreOrderTrav(T);
    cout << endl;

    cout << "IterInOrderTrav: ";
    tree.IterInOrderTrav(T);
    cout << endl;

    cout << "IterPostOrderTrav: ";
    tree.IterPostOrderTrav(T);
    cout << endl;

    return 0;
}

输入:ABD###C#F##
输出:
在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值