AVL搜索树,面试总结

本文介绍了AVL树的插入、删除操作,强调了在保持二叉搜索树特性的同时通过旋转调整平衡。涉及了右旋(RL)、左旋(Zig-Zag)以及高度调整、平衡因子等概念。同时,提到了Java实现的IndexedAVL类及其相关方法。
摘要由CSDN通过智能技术生成

// RL, 先右旋后左旋, 新节点位于t的右子树的左子树

void RL(Node *&t) {

zig(t->right);

zag(t);

}

// 插入操作,不仅要找到插入的位置,还要进行旋转进行高度的平衡

void insert(Node *&t, int value) {

if (t == nullptr) {

t = new Node(value);

return;

}

// 插入完成之后,自下而上的进行调整高度

if (value < t->value) { // 向左插入

insert(t->left, value);

int leftH = h(t->left);

int rightH = h(t->right);

if (leftH - rightH > 1) {

// LL 型

if (value <= t->left->value) {

LL(t);

// LR 型

} else if (value > t->left->value) {

LR(t);

}

}

} else if (value > t->value) { // 向右插入

insert(t->right, value);

int leftH = h(t->left);

int rightH = h(t->right);

if (rightH - leftH > 1) {

// RR型

if (value >= t->right->value) {

RR(t);

// RL型

} else if (value < t->right->value) {

RL(t);

}

}

}

pushUp(t);

}

void remove(Node *&p, int value) {

if (p == nullptr) return;

if (value < p->value) {

remove(p->left, value);

// 删除左子树的节点,唯一可能导致"失衡" 的情况是 bf由 -1 变成-2

int bf = balance_factor§;

if (bf < -1) {

if (h(p->right->right) >= h(p->right->left)) {

RR§;

} else {

RL§;

}

}

} else if (value > p->value) {

remove(p->right, value);

// 删除右子树的节点,唯一可能导致"失衡" 的情况是 bf由 1 变成 2

int bf = balance_factor§;

if (bf > 1) {

if (h(p->left->left) >= h(p->left->right)) {

LL§;

} else {

LR§;

}

}

} else {

// 下面细分成 3种情况 (左右子树都为空,一棵为空另一棵不为空,都不为空)

if (p->left == nullptr && p->right == nullptr) {

delete p;

p = nullptr;

} else if (p->left != nullptr && p->right == nullptr) {

Node *temp = p->left;

delete p;

p = temp;

} else if (p->left == nullptr && p->right != nullptr) {

Node *temp = p->right;

delete p;

p = temp;

} else {

// 用前驱的值代替(后继也是一样)

Node *cur = p->left;

while (cur->right != nullptr) {

cur = cur->right;

}

p->value = cur->value;

remove(p->left, cur->value);

// 这个地方仍然要有形态的调整

// 删除左子树的节点,唯一可能导致"失衡" 的情况是 bf由 -1 变成-2

int bf = balance_factor§;

if (bf < -1) {

if (h(p->right->right) >= h(p->right->left)) {

RR§;

} else {

RL§;

}

}

}

pushUp§;

}

}

bool query(Node *p, int value) {

if (p == nullptr) return false;

if (value < p->value) {

return query(p->left, value);

} else if (value > p->value) {

return query(p->right, value);

} else {

return true;

}

}

void helperDestructor(Node *node) {

if (node == nullptr) return;

helperDestructor(node->left);

helperDestructor(node->right);

delete node;

}

void inOrder(Node *node, vector &v) {

if (node == nullptr) return;

inOrder(node->left, v);

v.push_back(node->value);

inOrder(node->right, v);

}

};

int main() {

AVL avl;

for (int x = 1; x <= 15; x++) {

avl.insert(x);

}

vector v = {11,14,13,15,9,2,3,1,6,5,7};

for(int x:v){

avl.remove(x);

avl.displayLayerOrder();

}

return 0;

}

Java版

没有写删除节点的函数。

class IndexedAVL{

private static class Node{

// 节点存储的真实的数据

int val;

// size 是这节点统辖的树的节点的总个数,cnt这个节点存储val出现的次数, height是节点的高度

int size,cnt,height;

Node left,right;

public Node(int val) {

this.val = val;

this.cnt = this.height = this.size = 1;

}

}

private int size;

public int getSize() {

return size;

}

private Node root;

private int h(Node node){

return node==null?0:node.height;

}

private int getSize(Node p){

return p==null?0:p.size;

}

private void pushUp(Node p){

p.height = Math.max(h(p.left),h(p.right))+1;

p.size = p.cnt + getSize(p.left) + getSize(p.right);

}

// 右旋

private Node zig(Node p){

Node q = p.left;

p.left = q.right;

q.right = p;

pushUp§;

pushUp(q);

return q;

}

// 左旋

private Node zag(Node q){

Node p = q.right;

q.right = p.left;

p.left = q;

pushUp(q);

pushUp§;

return p;

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

img
img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip1024b 备注Java获取(资料价值较高,非无偿)
img

最后

现在其实从大厂招聘需求可见,在招聘要求上有高并发经验优先,包括很多朋友之前都是做传统行业或者外包项目,一直在小公司,技术搞的比较简单,没有怎么搞过分布式系统,但是现在互联网公司一般都是做分布式系统。

所以说,如果你想进大厂,想脱离传统行业,这些技术知识都是你必备的,下面自己手打了一份Java并发体系思维导图,希望对你有所帮助。

,真正体系化!**

[外链图片转存中…(img-xFDRj9Xu-1711538323148)]
[外链图片转存中…(img-lqzW7RdZ-1711538323149)]

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip1024b 备注Java获取(资料价值较高,非无偿)
[外链图片转存中…(img-0SXhPYXQ-1711538323149)]

最后

现在其实从大厂招聘需求可见,在招聘要求上有高并发经验优先,包括很多朋友之前都是做传统行业或者外包项目,一直在小公司,技术搞的比较简单,没有怎么搞过分布式系统,但是现在互联网公司一般都是做分布式系统。

所以说,如果你想进大厂,想脱离传统行业,这些技术知识都是你必备的,下面自己手打了一份Java并发体系思维导图,希望对你有所帮助。

[外链图片转存中…(img-q5CwoxAu-1711538323149)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值