右旋其实就是上面左旋的镜像过程,所以不难,直接仿写上面左旋的过程即可:
代码实现
TreeNode* RR(TreeNode* root) {
TreeNode* x = root->right; //即将返回的节点是y的右子节点
TreeNode* temp = x->left; //先把x的左子节点取出来
x->left = root; //把y放进x的左子节点
root->right = temp; //把前面预存的放到y的右子节点
return x;
}
int main() {
TreeNode* roott = new TreeNode(0);
vector vec = { 0,1,2,3,4,5,6,7};
createTree(vec,roott,0,vec.size()-1);
roott = RR(roott);
PreOrderTraverse(roott);
}
后面的部分,就比较抽象了。
LR(左右旋):在左叶节点的右侧插入数据
我们将这种情况抽象出来,得到下图:
我们需要对节点y进行平衡的维护。步骤如下图所示(第三个图里面x和z的位置换一下。):
代码实现
TreeNode* LR(TreeNode* root) {
root->left = RR(root->left);
root = LL(root);
return root;
}
//简单明了啊
RL(右左旋):在右叶节点的左侧插入数据
我们将这种情况抽象出来,得到下图:
我们需要对节点y进行平衡的维护。步骤如下图所示(第三个图里面x和z的位置换一下。):
第二个图中y的左孩子为T1
(被水印遮住的部分为:T1,T2,T3,T4)
代码实现
TreeNode* RL(TreeNode* root) {
root->right = LL(root->right);
root = RR(root);
return root;
}
//简单明了啊
在这里需要先补两个函数,虽然可能现在看不懂,但是配上调用函数的上下文就懂了。
计算平衡因子
int getBalanceFactor(TreeNode* node){
if(node==NULL){
return 0;
}
return get_depth(node->left)-getHeight(node->right);
}
int get_depth(TreeNode* node){
if(node==NULL){
return 0;
}
return node->depth;
}
对getBalanceFactor
函数返回值的分析:
-
如果刚插入的叶子节点的爷爷节点的返回值大于0
-
如果刚插入的叶子节点的父节点的返回值大于0:(LL)
-
如果刚插入的叶子节点的父节点的返回值小于0:(LR)
-
如果刚插入的叶子节点的爷爷节点的返回值小于0
-
如果刚插入的叶子节点的父节点的返回值大于0:(RL)
-
如果刚插入的叶子节点的父节点的返回值小于0:(RR)
更新有点慢了,这两天事情太多,加上要调整两地状态。
#include
#include
using namespace std;
class TreeNode {
public:
//这几个数据放做公有的,方便操作
int depth; //深度,这里计算每个结点的深度,通过深度的比较可得出是否平衡
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), depth(0), left(NULL), right(NULL) {}
TreeNode() : val(0), depth(0), left(NULL), right(NULL) {}
int getnode() {
return this->val;
}
TreeNode* getleft() {
return this->left;
}
TreeNode* getright() {
return this->right;
}
void setleft(TreeNode* node) {
this->left = node;
}
void setright(TreeNode* node) {
this->right = node;
}
};
void preorder(TreeNode* head) {
if (head == NULL) {
return;
}
cout << head->getnode() << endl;
preorder(head->getleft());
preorder(head->getright());
}
class AVL_Tree {
public:
AVL_Tree() {
}
TreeNode* right_rotate(TreeNode* root) {
TreeNode* temp = root->left;
root->left = temp->right;
temp->right = root;
return temp;
}
TreeNode* left_rotate(TreeNode* root) {
TreeNode* temp = root->right;
root->right = temp->left;
temp->left = root;
return temp;
}
TreeNode* right_left_rotate(TreeNode* root) {
root->right = right_rotate(root->right);
return left_rotate(root);
}
TreeNode* left_right_rotate(TreeNode* root) {
root->left = left_rotate(root->left);
return right_rotate(root);
}
int get_depth(TreeNode* node) {
if (!node) {
return 0;
}
int maxL = 0;
int maxR = 0;
//2.计算左子树的最大深度;
if (node->left != NULL)
maxL = get_depth(node->left);
//3.计算右子树的最大深度;
if (node->right != NULL)
maxR = get_depth(node->right);
//4.当前树的最大深度=左子树的最大深度和右子树的最大深度中的较大者+1
return maxL > maxR ? maxL + 1 : maxR + 1;
}
int getbalance(TreeNode* node) {
return get_depth(node->left) - get_depth(node->right);
}
//先假设这个二叉树足够高
TreeNode* insert_node(TreeNode* head,int val) { //插入一个节点,不管三七二十一先插到叶子节点再说
if (head != NULL) {
if (val < head->val) {
head->left = insert_node(head->left, val);
}
else {
head->left = insert_node(head->right, val);
}
}
else { //这里不放else等着失败
head = new TreeNode(val);
}
//插入之后就该旋转了
if (getbalance(head) == 2) { //如果需要旋转(左边高)
if (getbalance(head->left) == 1) { //左左,需要右右旋转
return right_rotate(head); //这里还需要向上衔接
}
else if (getbalance(head->left) == -1) { //左右,这里需要右左旋转
return right_left_rotate(head);
}
}
else if (getbalance(head) == -2) { //如果需要旋转(右边高)
if (getbalance(head->right) == -1) { //右右,需要左左旋转
return left_rotate(head); //这里还需要向上衔接
}
else if (getbalance(head->right) == -1){ //左右,这里需要右左旋转
return left_right_rotate(head);
}
}
return head;
}
TreeNode* delete_node(TreeNode* head,int val) {
if (head!=NULL) {
if (val < head->val) {
head->left = delete_node(head->left, val);
}
else if(val > head->val){
head->left = delete_node(head->right, val);
}
else {
TreeNode* temp = head->left;
while (temp && temp->right) {
temp = temp->right;
}
head->val = temp->val;
if (temp->left) { //如果最右子节点还有左子节点
//那顶多就一个节点
temp->val = temp->left->val;
//temp->left = temp->left->left;
//temp->right = temp->left->right;
temp->left->val = NULL;
delete temp->left;
}
else {
temp->val = NULL;
delete temp;
}
return NULL;
}
}
if (getbalance(head) == 2) { //如果需要旋转(左边高)
if (getbalance(head->left) == 1) { //左左,需要右右旋转
return right_rotate(head); //这里还需要向上衔接
}
else if (getbalance(head->left) == -1) { //左右,这里需要右左旋转
return right_left_rotate(head);
}
}
else if (getbalance(head) == -2) { //如果需要旋转(右边高)
if (getbalance(head->right) == -1) { //右右,需要左左旋转
return left_rotate(head); //这里还需要向上衔接
}
else if (getbalance(head->right) == -1) { //左右,这里需要右左旋转
return left_right_rotate(head);
}
}
return head;
}
};
int main() {
//TreeNode* a0 = new TreeNode(0);
TreeNode* a1 = new TreeNode(1);
//TreeNode* a2 = new TreeNode(2);
TreeNode* a3 = new TreeNode(3);
//TreeNode* a4 = new TreeNode(4);
TreeNode* a5 = new TreeNode(5);
TreeNode* a6 = new TreeNode(6);
TreeNode* a7 = new TreeNode(7);
//TreeNode* a8 = new TreeNode(8);
TreeNode* a9 = new TreeNode(9);
//TreeNode* a10 = new TreeNode(10);
a5->setleft(a3);
a5->setright(a7);
a3->setleft(a1);
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
Java核心架构进阶知识点
面试成功其实都是必然发生的事情,因为在此之前我做足了充分的准备工作,不单单是纯粹的刷题,更多的还会去刷一些Java核心架构进阶知识点,比如:JVM、高并发、多线程、缓存、Spring相关、分布式、微服务、RPC、网络、设计模式、MQ、Redis、MySQL、设计模式、负载均衡、算法、数据结构、kafka、ZK、集群等。而这些也全被整理浓缩到了一份pdf——《Java核心架构进阶知识点整理》,全部都是精华中的精华,本着共赢的心态,好东西自然也是要分享的
内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
些内容对你有帮助,可以扫码获取!!(备注Java获取)**
Java核心架构进阶知识点
面试成功其实都是必然发生的事情,因为在此之前我做足了充分的准备工作,不单单是纯粹的刷题,更多的还会去刷一些Java核心架构进阶知识点,比如:JVM、高并发、多线程、缓存、Spring相关、分布式、微服务、RPC、网络、设计模式、MQ、Redis、MySQL、设计模式、负载均衡、算法、数据结构、kafka、ZK、集群等。而这些也全被整理浓缩到了一份pdf——《Java核心架构进阶知识点整理》,全部都是精华中的精华,本着共赢的心态,好东西自然也是要分享的
[外链图片转存中…(img-TnlS7ej3-1713714894933)]
[外链图片转存中…(img-KKnwqeBA-1713714894933)]
[外链图片转存中…(img-lGovFnEK-1713714894933)]
内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!