二叉树常见问题

前言

  1. 最近在复习数据结构,将一些习题以代码的形式记录,作为笔记。
    不使用STL,算法题中假设栈、队列的maxSize足够大。
  2. 会持续更新。
struct Node {
    int data{0};
    Node *l{nullptr};
    Node *r{nullptr};
};

求非空二叉树的宽度(最多节点那层的节点数)

利用队列进行层次遍历,同时统计每一层的节点数

   int solve(Node *node){
        int ans_cnt = 0,  cnt = 0;
        Node *last = node; // 定义last指向当前层的最右边那个节点
        Node* q[maxSize]; int front = 0,rear = 0;
        q[++rear] = node; // 入队,
        while (rear != front){
            Node *p = q[++front]; // 出队
            cnt ++;
            if (p->l != nullptr) q[++rear] = p->l;
            if (p->r != nullptr) q[++rear] = p->r;
            if (p == last) { // 该层已经遍历完
                if (cnt > ans_cnt) ans_cnt = cnt;
                cnt = 0, last = q[rear];
            }
        }
        return ans_cnt;
    }

已知满二叉树的先序,求后序遍历

例如满二叉树的先序遍历为ABCDEFG,求其后序遍历(CDBFGEA)
思路:先序遍历建树即可。

#include "bits/stdc++.h"
using namespace std;
const int maxSize = 100;

string pre; // 二叉树先序遍历序列
char nodes[maxSize]; // 静态二叉树
int preId = 0;

// 根据满二叉树的先序遍历建树
void build(int id){
    if (id >= pre.size()+1) 
        return;
    nodes[id] = pre[preId++];
    build(id * 2);
    build(id * 2 + 1);
}
// 后序遍历二叉树s,下标从1开始
void pos(string& s,int id){
    if(id >= s.size())
        return;
    pos(s,id * 2);
    pos(s,id * 2 + 1);
    printf("%c",s[id]);
}
int main(){
    pre = "ABCDEFG";
    build(1); nodes[0] = ' ';
    string tree = string(nodes);
    pos(tree,1); //CDBFGEA
}

BST

class BST{
public:
    void insert(int x){
        insert(root,x);
    }
    // 查找用非递归
    Node *find(int x){
        Node *res = root;
        while (res != nullptr && res->data != x) res = res->data < x ? res->l : res->r;
        return res;
    }
    void createByVector(const vector<int> &a){
        for(int x:a) insert(x);
    }
    /**
     * 若度<=1,直接用子女代替
     * 否则用ceil代替,并递归删除ceil
     */
    void del(int x){
        del(root,x);
    }
    Node *get(){
        return root;
    }
private:
    Node *root{nullptr};
    void insert(Node *&node,int x){
        if (node == nullptr) node = new Node{x};
        else if (x < node->data) insert(node->l,x);
        else insert(node->r,x);
    }
    void del(Node *&p,int x){
        if (p == nullptr) return;
        else if (x < p->data) del(p->l,x);
        else if (x > p->data) del(p->r,x);
        else {
            if (p->l == nullptr || p->r == nullptr) {
                Node *d = p; p = p->l == nullptr ? p->r : p->l, delete(d);
            } else{
                Node *&ceil = p->r; while (ceil->l != nullptr) ceil = ceil->l;
                p->data = ceil->data;
                del(ceil,ceil->data); //问题转化为:删除ceil
            }
        }
    }
    /**
     * p的右子树作为根,中序遍历的第一个,因为中序遍历为 l root r, BST 中 l < root < r
     * @return BST,最接近 p 且大于 p 的节点,不存在则返回null
     */
     Node *getCeil(Node *p,int x){
         p = p->r; while (p->l != nullptr) p = p->l;
        return p;
     }
};

平衡二叉树AVL

class AVL{
public:
    Node *get(){
        return root;
    }
    Node *createByVector(vector<int> &a){
        root = nullptr;
        for(int v:a) insert(v);
        return root;
    }
    void insert(int v){
        root = insert(root,v);
    }

private:
    Node *root{nullptr};
    Node* insert(Node *p,int v){
        if (p == nullptr) return new Node{v};
        else if (v < p->data) p->l = insert(p->l,v);
        else p->r = insert(p->r,v);
        updateHeight(p);
        return balance(p);
    }

    void updateHeight(Node *p){
        p->h = max(height(p->l),height(p->r)) + 1;
    }

    Node* balance(Node *p){
        int fac = balanceFac(p);
        if (fac > 1 && balanceFac(p->l) > 0) return rightRotate(p); // LL
        if (fac < -1 && balanceFac(p->r) < 0) return leftRotate(p); // RR
        if (fac > 1 && balanceFac(p->l) < 0) { // LR
            p->l = leftRotate(p->l);
            return rightRotate(p);
        }
        if (fac < -1 && balanceFac(p->r) > 0){ // RL
            p->r = rightRotate(p->r);
            return leftRotate(p);
        }
        return p; // 不需要调整
    }

    int height(Node *p){
        return p == nullptr ? 0 : p->h;
    }

    int balanceFac(Node* p){
        return p == nullptr ? 0 : height(p->l) - height(p->r);
    }

    Node *leftRotate(Node *p){
        Node *res = p->r;
        p->r = res->l, res->l = p;
        updateHeight(p); updateHeight(res);
        return res;
    }

    Node *rightRotate(Node *p){
        Node *res = p->l;
        p->l = res->r, res->r = p;
        updateHeight(p); updateHeight(res);
        return res;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值