主要是方便以后取用直接上代码了,代码中有注释

因为这些操作几乎都与递归有关,所以建议先巩固好递归的知识

#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#define maxn 1000005
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;
struct node {    //首先定义一个结构体(注意:c语言定义时会有小小的区别)
    int date;    //存放数据
    node* left;
    node* right;
};
struct Tree {   //这一步让树更加完整(每次访问一棵树时只需要知道他的根节点)
    node* root;
};

//以上是我们所有需要的数据结构

void ins(Tree* tree, int values) {    //插入值
    node* node1 = (node*)malloc(sizeof(node));  //设计内存管理,当函数退出时,不会被销毁掉(不熟悉的查阅malloc用法)
    node1->date = values;      //因为是个新结点,所以左右指针为空,接下来就是将这个结点插入到这棵树当中
    node1->left = NULL;
    node1->right = NULL;
    if (tree->root == NULL) {   //第一种可能:这棵树本来就是一个空树,直接用来做根节点
        tree->root = node1;
    }
    else {                  //如果已经有根节点
        node* temp = tree->root;   //temp就是 当前我这个values要跟某个节点进行比较,temp就是这个结点
        while (temp != NULL) {      //如果结点不为空,持续比较
            if (values < temp->date) {  //如果values比temp的date域小我们走左边,反之走右边
                if (temp->left == NULL) {  //走左边也分为两种情况,第一种就是左边直接为空结点,所以我们直接插入
                    temp->left = node1;    
                    return; 
                }
                else {
                    temp = temp->left;   //第二种情况就是:不为空,那么我们跑到左分支继续探测
                }
            }
            else {     //同理
                if (temp->right == NULL) {
                    temp->right = node1;
                    return;
                }
                else {
                    temp = temp->right;
                }
            }
        }
    }
}
void preorder(node* node1) {  //先序 三个遍历方法都是用的递归,不明白的话复习一下递归的内容
    if (node1 != NULL) {
        printf("%d ", node1->date);  
        preorder(node1->left);
        preorder(node1->right);
    }
}
void inorder(node* node1) {  //中序
    if (node1 != NULL) {
        inorder(node1->left);
        printf("%d ", node1->date);
        inorder(node1->right);
    }
}
void postorder(node* node1) {   //后续
    if (node1 != NULL) {
        postorder(node1->left);
        postorder(node1->right);
        printf("%d ", node1->date);
    }

}

int get_maxnum(node* node1) {   //求最大值
    if (node1 == NULL) {    //如果直接为空树,则最大值不存在返回-1
        return -1;
    }
    else {   //递归实现
        int m1 = get_maxnum(node1->left);  //设左节点的值为m1
        int m2 = get_maxnum(node1->right);  //设右节点的值为m2
        int imax = node1->date;          //根节点的值为imax
        imax = max(m1, max(imax, m2));   //求出三点最大值
        return imax;
    }
}

int get_hight(node* node1) {   //求树的高度
    if (node1 == NULL) {   //如果为空树,返回0
        return 0; 
    }
    else {      //因为树的高度与最长的那条分支有关,所以我们只需要找出左边或者右边哪边更高一些
        int left_h = get_hight(node1->left);    //左分支的高度
        int right_h = get_hight(node1->right);  //右分支高度
        int imax = max(left_h, right_h);
        return imax + 1;  //注意!! 一定不要忘记+1,因为根节点有1高度
    }
}

int main()
{
    int x, n;
    Tree tree;
    tree.root = NULL;  //树为空
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> x;
        ins(&tree, x);
    }
    preorder(tree.root);
    cout << endl;
    inorder(tree.root);
    cout << endl;
    postorder(tree.root);
    cout << endl;

    cout << "树的高度 " << get_hight(tree.root) << endl;

    cout << "树的最大值 " << get_maxnum(tree.root) << endl;
    return 0;
}