【算法】二叉树相关问题

#ifndef LINK_NODE
#define LINK_NODE

typedef struct Node{
    int value;
    struct Node* next;
}Node;

typedef struct TNode{
    int value;
    struct TNode* left;
    struct TNode* right;
}TNode;

typedef struct SubTree{
    int maxValue;
    int minValue;
    bool isBST;
}SubTree;

typedef struct BSubTree{
    bool isBalanced;
    int height;
}BSubTree;

#endif
//
// Created by runac on 2024/12/15.
//
#include "Node.h"
#include <iostream>
#include <stack>
#include <queue>
#include <map>
#include <cmath>

// 递归 先序遍历
void PreorderTraverse(TNode* root){
    if(root == nullptr){
        return;
    }
    std::cout << root -> value << " ";
    PreorderTraverse(root -> left);
    PreorderTraverse(root -> right);
}

// 递归 中序遍历
void InorderTraverse(TNode* root){
    if(root == nullptr){
        return;
    }
    InorderTraverse(root -> left);
    std::cout << root -> value << " ";
    InorderTraverse(root -> right);
}

// 递归 后序遍历
void PostorderTraverse(TNode* root){
    if(root == nullptr){
        return ;
    }
    PostorderTraverse(root -> left);
    PostorderTraverse(root -> right);
    std::cout << root -> value << " ";
}

// 非递归 先序遍历 使用栈
void PreorderTraverse_NonRecursive(TNode* root){
    if(root != nullptr){
        std::stack<TNode*> s;
        s.push(root);
        while(!s.empty()){
            TNode* p = s.top();
            std::cout << p -> value << " ";
            s.pop();
            if(p -> right != nullptr){
                s.push(p -> right);
            }
            if(p -> right != nullptr){
                s.push(p -> left);
            }
        }
    }
}

// 非递归 中序遍历 使用栈
void InorderTraverse_NonRecursive(TNode* root){
    if(root != nullptr){
        std::stack<TNode*> s;
        TNode* p = root;
        while(!s.empty() || p != nullptr){
            if(p != nullptr){
                s.push(p);
                p = p -> left;
            }
            else{
                p = s.top();
                s.pop();
                std::cout << p -> value << " ";
                p = p -> right;
            }
        }
    }
}

// 非递归 后序遍历 使用两个栈
void PostorderTraverse_NonRecursive(TNode* root){
    if(root != nullptr){
        std::stack<TNode*> f;
        std::stack<TNode*> s;
        f.push(root);
        while(!f.empty()){
            TNode* p = f.top();
            s.push(p);
            f.pop();
            if(p -> left != nullptr){
                f.push(p -> left);
            }
            if(p -> right != nullptr){
                f.push(p -> right);
            }
        }
        while(!s.empty()){
            std::cout << s.top() -> value << " ";
            s.pop();
        }
    }
}

// 层次遍历 队列
void LevelTraverse(TNode* root){
    std::queue<TNode*> q;
    q.push(root);
    while(!q.empty()){
        TNode* p = q.front();
        std::cout << p -> value << " ";
        if(p -> left != nullptr){
            q.push(p -> left);
        }
        if(p -> right != nullptr){
            q.push(p -> right);
        }
        q.pop();
    }
}

// 找到树的最宽宽度 使用map,队列
int FindTreeMaxWidth(TNode* root){
    if(root == nullptr) {
        return 0;
    }

    std::map<TNode*, int> m;
    std::queue<TNode*> q;
    int maxWidth = 0;
    int curWidth = 0;
    int level = 1;

    m[root] = 1;
    q.push(root);
    while(!q.empty()){
        std::cout << "level " <<  level << std::endl;
        TNode* p = q.front();
        if(level == m[p]){
            curWidth ++;
            if(p -> left != nullptr){
                q.push(p -> left);
                m[p -> left] = m[p] + 1;
            }
            if(p -> right != nullptr){
                q.push(p -> right);
                m[p -> right] = m[p] + 1;
            }
            q.pop();
        }
        else{
            std::cout << "maxWidth: " <<  maxWidth << std::endl;
            std::cout << "curWidth: " <<  curWidth << std::endl;
            maxWidth = maxWidth > curWidth ? maxWidth : curWidth;
            curWidth = 0;
            level ++;
        }
    }
    maxWidth = maxWidth > curWidth ? maxWidth : curWidth;
    return maxWidth;
}

// 判断一颗树是否为搜索二叉树 递归
int preValue = INT32_MIN;
bool CheckBinSearchTree_Recursive(TNode* root){
    if(root == nullptr) return true;
    bool l = CheckBinSearchTree_Recursive(root -> left);
    std::cout << root -> value << ", ";
    if(root -> value < preValue) return false;
    else{
        preValue = root -> value;
        std::cout << root -> value << ", ";
    }
    bool r = CheckBinSearchTree_Recursive(root -> right);
    std::cout << root -> value << ", ";
    return l && r;
}

// 判断一棵树是否为搜索二叉树 非递归
bool CheckBinSearchTree_NonRecursive(TNode* root){
    std::stack<TNode*> s;

    while(!s.empty() || root != nullptr){
        if(root != nullptr){
            s.push(root);
            root = root -> left;
        }else{
            TNode* p = s.top();
            if(p -> value < preValue){
                return false;
            }else{
                preValue = p -> value;
            }
            s.pop();
            root = p -> right;
        }
    }
    return true;
}

// 判断一棵树是否为搜索二叉树 递归+特殊结构
SubTree CheckBinSearchTree(TNode* root){

    if(root == nullptr) return {0, 0, true};
    if(root -> left == nullptr && root -> right == nullptr) {
        std::cout << "叶节点: " << root -> value << std::endl  ;
        return {root -> value, root -> value, true};
    }
    SubTree leftSubTree = CheckBinSearchTree(root -> left);
    SubTree rightSubTree = CheckBinSearchTree(root -> right);
    if(!leftSubTree.isBST || !rightSubTree.isBST
    || leftSubTree.maxValue > root -> value || rightSubTree.minValue < root -> value){
        return {rightSubTree.maxValue, leftSubTree.minValue, false};
    }
    else{
        std::cout << "当前节点: " << root -> value << " 左子树最大值: " << leftSubTree.maxValue << " 右子树最小值: " << rightSubTree.minValue << std::endl;
        return {rightSubTree.maxValue, leftSubTree.minValue, true};
    }
}

// 判断一棵二叉树是满二叉树
bool CheckFullBinTree(TNode* root){
    std::queue<TNode*> q;
    std::map<TNode*, int> m;
    q.push(root);
    m[root] = 1;
    int count = 1;
    int level = 1;

    while(!q.empty()){
        TNode* n = q.front();
        std::cout << level << std::endl;
        if(m[n] == level){
            q.pop();
            if(n -> left != nullptr){
                q.push(n -> left);
                m[n -> left] = level + 1;
                count ++;
            }
            if(n -> right != nullptr){
                q.push(n -> right);
                m[n -> right] = level + 1;
                count ++;
            }
        }else{
            std::cout << "节点数: " << count << std::endl;
            level ++ ;
        }
    }
    std::cout << "层数: " << level << " 节点数: " << count << std::endl;
    return count == pow(2, level) - 1;
}

// 判断一棵树是否为完全二叉树
bool  isCBT(TNode* root){
    if(root == nullptr) return true;

    std::queue<TNode*> q;
    q.push(root);
    bool isLeaf = false;

    while(!q.empty()){
        TNode* p = q.front();
        if((p -> left == nullptr && p -> right != nullptr)||(isLeaf && (p -> left != nullptr || p -> right != nullptr))){
            return false;
        }
        if(p -> left == nullptr && !isLeaf){
            isLeaf = true;
        }
        else{
            if(p -> left != nullptr){
                q.push(p -> left);
            }
            if(p -> right != nullptr){
                q.push(p -> right);
            }
        }
        q.pop();
    }
    return true;
}

// 如何判断一棵树是平衡二叉树 递归+特殊结构
BSubTree isBBT(TNode* root){
    if(root == nullptr) return BSubTree{true, 0};
    BSubTree l = isBBT(root -> left);
    BSubTree r = isBBT(root -> right);

    int height = l.height > r.height ? l.height : r.height;
    bool isBalanced = l.isBalanced && r.isBalanced && abs(l.height - r.height) <= 1;
    return BSubTree{isBalanced, height};
}

int main(){
//    TNode n8{9, nullptr, nullptr};
    TNode n7{7, nullptr, nullptr};
    TNode n6{3, nullptr, nullptr};
    TNode n5{7, nullptr, nullptr};
    TNode n4{0, nullptr, nullptr};
    TNode n3{4, &n6, &n7};
    TNode n2{1, &n4, &n5};
    TNode n1{2, &n2, &n3};

//    InorderTraverse_NonRecursive(&n1);
    if(CheckBinSearchTree_NonRecursive(&n1)){
        std::cout << "是搜索二叉树" << std::endl;
    }
    else{
        std::cout << "不是搜索二叉树" << std::endl;
    }
    if(isCBT(&n1)){
        std::cout << "是完全二叉树" << std::endl;
    }
    else{
        std::cout << "不是完全二叉树" << std::endl;
    }
    if(isBBT(&n1).isBalanced){
        std::cout << "是平衡二叉树" << std::endl;
    }
    else{
        std::cout << "不是平衡"
                     "二叉树" << std::endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

想考北航的小刺猬

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

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

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

打赏作者

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

抵扣说明:

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

余额充值