zoukankan      html  css  js  c++  java
  • 二叉树相关

    #include <iostream>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <map>

    template <class T>
    typedef struct node {
    node* left;
    node* right;
    T val;
    std::string ext;
    node(T val) : left(nullptr), right(nullptr), val(val), ext(""){}
    };
    typedef node<int> Node;
    Node* creat_normal_tree() {
    Node* pRoot = new Node(5);
    pRoot->left = new Node(3);
    pRoot->left->left = new Node(1);
    pRoot->left->right = new Node(4);
    pRoot->right = new Node(8);
    pRoot->right->left = new Node(7);
    pRoot->right->right = new Node(9);
    return pRoot;
    }
    Node* creat_normal_tree2() {
    Node* pRoot = new Node(5);
    pRoot->left = new Node(8);
    pRoot->left->left = new Node(9);
    pRoot->left->right = new Node(7);
    pRoot->right = new Node(3);
    pRoot->right->left = new Node(4);
    pRoot->right->right = new Node(1);
    return pRoot;
    }
    #define CHECK_NULL_RET(pRoot, ret) {
    if (nullptr == pRoot) {
    return ret;
    }
    }
    #define CHECK_NULL_VOID(pRoot) {
    if (nullptr == pRoot) {
    return;
    }
    }

    /*************************二叉树遍历*****************************/
    // 前序
    void pre_order_r(Node* pRoot) {
    if (nullptr == pRoot) {
    return;
    }
    std::cout << pRoot->val << ",";
    pre_order_r(pRoot->left);
    pre_order_r(pRoot->right);
    }
    void pre_order_stack(Node* pRoot) {
    if (nullptr == pRoot) {
    return;
    }
    Node* pCur = pRoot;
    std::stack<Node*> helper;
    helper.push(pCur);
    while (!helper.empty()) {
    Node* pTmp = helper.top();
    helper.pop();
    std::cout << pTmp->val << ",";
    if (pTmp->right) {
    helper.push(pTmp->right);
    }
    if (pTmp->left) {
    helper.push(pTmp->left);
    }
    }

    }
    // 中序
    void in_order_r(Node* pRoot) {
    if (nullptr == pRoot) {
    return;
    }
    in_order_r(pRoot->left);
    std::cout << pRoot->val << ",";
    in_order_r(pRoot->right);
    }
    void in_order_stack(Node* pRoot) {
    if (nullptr == pRoot) {
    return ;
    }
    std::stack<Node*> helper;
    Node* pCur = pRoot;
    while (pCur || !helper.empty()) {
    if (pCur) {
    helper.push(pCur);
    pCur = pCur->left;
    } else {
    Node* pTop = helper.top();
    helper.pop();
    std::cout << pTop->val << ",";
    pCur = pTop->right;
    }
    }
    }
    // 后序
    void post_order_r(Node* pRoot) {
    if (nullptr == pRoot) {
    return;
    }
    post_order_r(pRoot->left);
    post_order_r(pRoot->right);
    std::cout << pRoot->val << ",";
    }
    void post_order_stack(Node* pRoot) {
    if (nullptr == pRoot) {
    return;
    }
    std::stack<Node*> helper;
    Node* pCur = pRoot;
    while (pCur || !helper.empty()) {
    if (pCur) {
    helper.push(pCur);
    pCur = pCur->left;
    } else {
    Node* pTop = helper.top();
    if (std::strcmp(pTop->ext.c_str(), "visited") == 0) {
    std::cout << pTop->val << ",";
    helper.pop();
    } else {
    pTop->ext = "visited";
    pCur = pTop->right;
    }

    }
    }
    }
    // 层序遍历, 同时按照层数保存数据
    void leve_order_queue(Node* pRoot, std::map<int, std::vector<int>> &s_out) {
    if (nullptr == pRoot) {
    return;
    }
    std::queue<Node*> helper;
    helper.push(pRoot);
    std::vector<int> vec;
    Node* pHelper = new Node(-1);
    pHelper->ext = "helper";
    helper.push(pHelper);
    int level = 1;
    while (!helper.empty()) {
    Node* pFront = helper.front();
    helper.pop();
    if (strcmp(pFront->ext.c_str(), "helper") == 0) {
    if (helper.empty()) {
    break;
    } else {
    ++level;
    helper.push(pHelper);
    }
    } else {
    std::cout << pFront->val << ",";
    s_out[level].push_back(pFront->val);
    if (pFront->left) {
    helper.push(pFront->left);
    }
    if (pFront->right) {
    helper.push(pFront->right);
    }
    }
    }
    }
    /*************************Search end*****************************/


    /*************************合并两个二叉搜索树*****************************/
    // step 1 get in order arrs
    void get_order_arr(Node* pRoot, std::vector<int> &out) {
    if (nullptr == pRoot) {
    return;
    }
    get_order_arr(pRoot->left, out);
    out.push_back(pRoot->val);
    get_order_arr(pRoot->right, out);
    }
    // step 2 insert node into bst
    Node* insert_node_into_bst(Node* pRoot, int val) {
    if (nullptr == pRoot) {
    pRoot = new Node(val);
    return pRoot;
    }
    // val != pRoot->val in bst
    if (pRoot->val < val) {
    pRoot->right = insert_node_into_bst(pRoot->right, val);
    }
    if (pRoot->val > val) {
    pRoot->left = insert_node_into_bst(pRoot->left, val);
    }
    return pRoot;
    }
    // step 3 Merge
    Node* merge_bsts(Node* pRoot1, Node* pRoot2) {
    // special cases
    if (nullptr == pRoot1 && nullptr == pRoot2) {
    return nullptr;
    }
    if (nullptr == pRoot1) {
    return pRoot2;
    }
    if (nullptr == pRoot2) {
    return pRoot1;
    }

    // in order arr
    std::vector<int> helper;
    get_order_arr(pRoot1, helper);

    // insert into tree2
    for (auto itr:helper) {
    insert_node_into_bst(pRoot2, itr);
    }
    return pRoot2;
    }
    /*************************合并两个二叉搜索树*****************************/

    /*************************二叉树最大深int度*****************************/
    int get_max_depth(Node* pRoot) {
    CHECK_NULL_RET(pRoot, 0);
    int left = get_max_depth(pRoot->left) + 1;
    int right = get_max_depth(pRoot->right) + 1;
    return std::max(left, right);
    }
    /*************************二叉树最大深度*****************************/

    /*************************二叉树最小深度*****************************/
    int get_min_depth(Node* pRoot) {
    CHECK_NULL_RET(pRoot, 0);
    int left = get_min_depth(pRoot->left);
    int right = get_min_depth(pRoot->right);
    if (left * right == 0) {
    return (left + right + 1);
    } else {
    return std::min(left + 1, right + 1);
    }
    }
    /*************************二叉树最小深度*****************************/

    /*************************重建二叉树*****************************/
    Node* rebuild_tree_by_pre_in_arrs(std::vector<int> &pre_order, std::vector<int> &in_order) {
    // 递归终止
    if (pre_order.size() == 1) {
    return new Node(pre_order[0]);
    }
    if (in_order.size() == 1) {
    return new Node(in_order[0]);
    }

    // 创建根节点
    Node* pRoot = new Node(pre_order[0]);
    // 左子树中序
    std::vector<int> left_in;
    // 左树节点数量
    int left_cnt = 0;
    for (int i=0; i < in_order.size(); ++i) {
    if (pre_order[0] == in_order[i]) {
    break;
    } else {
    ++left_cnt;
    left_in.push_back(in_order[i]);
    }
    }
    // 左树先序
    std::vector<int> left_pre(pre_order.begin() + 1, pre_order.begin() + left_cnt + 1);
    // 右树先序
    std::vector<int> right_pre(pre_order.begin() + left_cnt + 1, pre_order.end());
    // 右树中序
    std::vector<int> right_in(in_order.begin() + left_cnt + 1, in_order.end());

    pRoot->left = rebuild_tree_by_pre_in_arrs(left_pre, left_in);
    pRoot->right = rebuild_tree_by_pre_in_arrs(right_pre, right_in);

    return pRoot;
    }
    /*************************重建二叉树*****************************/

    /*************************二叉树叶子节点个数*****************************/
    int get_nodes_cnt(Node* pRoot) {
    if (nullptr == pRoot) {
    return 0;
    }
    if (nullptr == pRoot->left && nullptr == pRoot->right) {
    return 1;
    }
    return get_nodes_cnt(pRoot->left) + get_nodes_cnt(pRoot->right) + 1;
    }
    /*************************二叉树节点个数*****************************/

    /*************************判断二叉树是否是平衡二叉树*****************************/
    // 判断以pRoot为根节点的树是否是平衡的
    int is_node_balanced(Node* pRoot) {
    if (nullptr == pRoot) {
    return 0;
    }
    int left = is_node_balanced(pRoot->left);
    int right = is_node_balanced(pRoot->right);
    // 如果当前节点子节点不平衡, 或者当前节点本身不平衡, 返回-1
    if (left == -1 || right == -1 || std::abs(left - right) > 1) {
    return -1;
    }
    // 如果当前节点是平衡的, 返回当前节点的最大深度
    return std::max(left, right) + 1;
    }
    bool is_avl(Node* pRoot) {
    return is_node_balanced(pRoot) == -1 ? false : true;
    }
    /*************************判断二叉树是否是平衡二叉树*****************************/

    /*************************两个二叉树是否完全相同*****************************/
    bool is_same_tree(Node* pRoot1, Node* pRoot2) {
    if (nullptr == pRoot1 && nullptr == pRoot2) {
    return true;
    }
    if (nullptr == pRoot1 || nullptr == pRoot2) {
    return false;
    }
    if (pRoot1->val != pRoot2->val) {
    return false;
    }
    return is_same_tree(pRoot1->left, pRoot2->left) && is_same_tree(pRoot1->right, pRoot2->right);
    }
    /*************************两个二叉树是否完全相同*****************************/

    /*************************两个二叉树是否互为镜像*****************************/
    bool is_mirror_trees(Node* pRoot1, Node* pRoot2) {
    if (nullptr == pRoot1 && nullptr == pRoot2) {
    return true;
    }
    if (nullptr == pRoot1 || nullptr == pRoot2) {
    return false;
    }
    if (pRoot1->val != pRoot2->val) {
    return false;
    }
    return is_mirror_trees(pRoot1->left, pRoot2->right) && is_mirror_trees(pRoot1->right, pRoot2->left);
    }
    /*************************两个二叉树是否互为镜像*****************************/

    /*************************求二叉树的镜像*****************************/
    Node* get_mirror_tree(Node* pRoot) {
    if (nullptr == pRoot) {
    return nullptr;
    }
    pRoot->left = get_mirror_tree(pRoot->right);
    pRoot->right = get_mirror_tree(pRoot->left);
    return pRoot;
    }
    /*************************求二叉树的镜像*****************************/

    /*************************求两个二叉树的最低公共祖先节点*****************************/
    bool find_node(Node* pNode, Node* pRoot) {
    if (nullptr == pRoot || nullptr == pNode) {
    return false;
    }
    if (pNode->val == pRoot->val) {
    return false;
    }
    return find_node(pNode, pRoot->left) || find_node(pNode, pRoot);
    }
    Node* find_latest_common_ancestor(Node* pNode1, Node* pNode2, Node* pRoot) {
    if (find_node(pNode1, pRoot->left)) {
    if (find_node(pNode2, pRoot->right)) {
    return pRoot;
    } else {
    return find_latest_common_ancestor(pNode1, pNode2, pRoot->left);
    }
    } else {
    if (find_node(pNode2, pRoot->left)) {
    return pRoot;
    } else {
    find_latest_common_ancestor(pNode1, pNode2, pRoot->right);
    }
    };

    }
    /*************************求两个二叉树的最低公共祖先节点*****************************/

    /*************************输入一个二叉树和一个整数,打印出二叉树中节点值的和等于输入整数所有的路径*****************************/
    void get_root_path(Node* pRoot, int target, std::vector<std::vector<Node*>> &out, std::vector<Node*> helper) {
    if (nullptr == pRoot) {
    return;
    }
    helper.push_back(pRoot);
    if (nullptr == pRoot->left && nullptr == pRoot->right && target - pRoot->val == 0) {
    out.push_back(helper);
    helper.clear();
    }
    if (pRoot->left) {
    get_root_path(pRoot->left, target-pRoot->val, out, helper);
    }
    if (pRoot->right) {
    get_root_path(pRoot->right, target-pRoot->val, out, helper);

    }
    helper.pop_back();
    }
    /*************************输入一个二叉树和一个整数,打印出二叉树中节点值的和等于输入整数所有的路径*****************************/

    /*************************二叉树内两个节点的最长距离*****************************/
    /*************************二叉树内两个节点的最长距离*****************************/

    /*************************1-N个数可以构成多少个不同的二叉搜索树*****************************/
    int get_bst_cnt(int N) {
    std::vector <int> helper(N+1, 0);
    helper[0] = 1;
    helper[1] = 1;

    for (int i = 2; i <= N; ++i) {
    // 当 N=i 时
    for (int root = 0; root < i; ++root) {
    // 左子树个数*右子树个数
    int cur = helper[root] * helper[i-root -1];
    helper[i] += cur;
    }
    }
    return helper[N];
    }
    // https://blog.csdn.net/sinat_35261315/article/details/78678961
    /*************************1-N个数可以构成多少个不同的二叉搜索树*****************************/


    /*************************判断二叉树是否是完全二叉树*****************************/
    bool is_completed_tree(Node* pRoot) {

    }
    /*************************判断二叉树是否是完全二叉树*****************************/


    int main() {
    std::cout << "Hello, World!" << std::endl;
    Node* pRoot = creat_normal_tree();
    in_order_r(pRoot);
    std::cout << std::endl;
    std::vector<std::vector<Node*>> out;
    std::vector<Node*> helper;
    get_root_path(pRoot, 12, out, helper);
    int a = 1;
    return 0;
    }
    除特殊说明外,其余所有文章均属原创。未经允许,请勿进行转载或者其他操作 有问题欢迎留言交流
  • 相关阅读:
    Spring Boot 启动加载数据 CommandLineRunner(一般用于项目启动时,用户信息的缓存)
    缓存穿透、缓存并发、缓存失效之思路变迁
    知识点的梳理
    windows下查找java应用占用CPU过高问题
    Java开发中的Memcache原理及实现
    malloc函数详解 C语言逻辑运算符
    PCH 警告:标头停止点不能位于宏或#if块中
    绪论-第一章-《数据结构题集》
    线性表的顺序存储结构--用数组实现
    第二章 《C++ Primer Plus》
  • 原文地址:https://www.cnblogs.com/LiuBingBlogs/p/13929522.html
Copyright © 2011-2022 走看看