前言
- 最近在复习数据结构,将一些习题以代码的形式记录,作为笔记。
不使用STL,算法题中假设栈、队列的maxSize足够大。 - 会持续更新。
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;
}
};