当前位置:网站首页>平衡二叉搜索树
平衡二叉搜索树
2022-06-24 19:28:00 【翁炜强】
”code is art that makes our heart sing "
--2021.8.28
定义:
1.一棵二叉搜索树,满足右节点大于(或等于父节点),左节点小于(或等于)父节点
2.同时又满足每个节点的左子树的高度减去右子树的高度不大于1,即为-1 0 1.
涉及知识点:
1.插入
分为以下几种情况:LL型 RR型 LR型 RL型
编程反思:1.root=nullptr 根节点一开始要设为空 2.用指针和取地符访问均可以3.递归要有终止条件
LL型:
RR型:
RL型:
LR型:
层次遍历:
1.采用队列的形式
2.先将根节点放入,过后再逐步放入各节点的左右节点
模板代码:
#include<bits/stdc++.h>
#include<assert.h>
using namespace std;
#define MAX_SIZE 128
template<typename T>
class AVLNode
{
public:
AVLNode<T>() : left(NULL),right(NULL),parent(NULL), height(1) {}
AVLNode<T>(T data) : left(NULL), right(NULL), parent(NULL), data(data), height(1) {}
~AVLNode() {};
T data;
int height;
AVLNode<T>* left;
AVLNode<T>* right;
AVLNode<T>* parent;
};
template<typename T>
class Queue
{
public:
Queue<T>() : front(-1), rear(-1) { data[MAX_SIZE] = {}; }
int front;
int rear;
AVLNode<T>* data[MAX_SIZE];
};
template<typename T>
void initQueue(Queue<T>* q)
{
q->front = q->rear = -1;
}
template<typename T>
bool emptyQueue(Queue<T>* q)
{
if (q->front == q->rear)
{
return true;
}
return false;
}
template<typename T>
bool enQueue(Queue<T>* q, AVLNode<T>*& node)
{
if (q->rear == MAX_SIZE - 1)//队列已满
{
return false;
}
q->rear++;//在队尾进行添加
q->data[q->rear] = node;
return true;
}
template<typename T>
bool deQueue(Queue<T>* q, AVLNode<T>*& node)
{
if (q->front == q->rear)//队列为空
{
return false;
}
q->front++;//
node = q->data[q->front];//更改值
return true;
}
template<typename T>
class AVLTree
{
private:
public:
AVLNode<T>* root;
AVLTree<T>() { this->root = nullptr ; };
~AVLTree<T>() { delete root; };
void _insert(T data)
{
if (nullptr == this->root)
{
this->root = new AVLNode<T>(data);//先判断空再创建
return;//记得return
}
this->root=_insert(this->root, data);
}
AVLNode<T>* _insert(AVLNode<T>* &root, T data)
{
//插入左子树和右子树
if (/*nullptr!=root*/data < root->data)
{
if (nullptr == root->left)
{
root->left = new AVLNode<T>(data);
root->left->parent=root;//创建链接这个很重要
}
else
{
_insert(root->left, data);//递归要有终止条件
}
}
else if(data>root->data)
{
if (nullptr == root->right)
{
root->right = new AVLNode<T>(data);
root->right->parent = root;//这个步骤很重要
}
else
{
_insert(root->right, data);
}
}
//旋转操作
root->height = calHeight(root);
if (calBF(root) == 2)//说明是LL型
{
//如果是LR型
if (calBF(root->left) == -1)
{
root->left = leftRotate(root->left);//先左旋
}
root = rightRotate(root);//后右旋
}
if (calBF(root) == -2)//说明是RR型
{
if (calBF(root->right) == 1)//说明是RL型
{
root->right = rightRotate(root->right);
}
root = leftRotate(root);
}
return root;
}
void preOrder()
{
preOrder(root);
}
void preOrder(AVLNode<T>* root)
{
if (nullptr == root)
{
return;
}
cout << root->data << " " << "height:" << root->height << endl;
preOrder(root->left);
preOrder(root->right);
}
void inOrder()
{
inOrder(root);
}
void inOrder(AVLNode<T>* root)
{
if (nullptr == root)
{
return;
}
inOrder(root->left);
cout << root->data << " " << "height:" << root->height << endl;
inOrder(root->right);
}
void postOrder()
{
postOrder(root);
}
void postOrder(AVLNode<T>* root)
{
if (nullptr == root)
{
return;
}
postOrder(root->left);
postOrder(root->right);
cout << root->data << " " << "height:" << root->height << endl;
}
void layerOrder()
{
Queue<T>* q = new Queue<T>();
initQueue(q);
if (nullptr != this->root)
{
enQueue(q, this->root);//先将根节点入队
}
while (!emptyQueue(q))
{
deQueue(q, this->root);//出队
cout << this->root->data << " ";//root是不断更新的
if (nullptr != this->root->left)//先将左结点入队 再将右结点入队 确保先从右边输出
{
enQueue(q, this->root->left);
}
if (nullptr != this->root->right)//
{
enQueue(q, this->root->right);
}
}
}
int calHeight(AVLNode<T>* root);//计算高度 高度从下往上 深度从上往下
int calBF(AVLNode<T>* root);//计算平衡因子
AVLNode<T>* leftRotate(AVLNode<T>* root);
AVLNode<T>* rightRotate(AVLNode<T>* root);
};
//Node类函数
template <typename T>
int AVLTree<T>::calHeight(AVLNode<T>* root)
{
if (root->left == NULL && root->right == NULL)
{
return 1;
}
else if (root->left == NULL)
{
return root->right->height + 1;
}
else if (root->right == NULL)
{
return root->left->height + 1;
}
else
{
return root->left->height > root->right->height ? root->left->height + 1 : root->right->height + 1;
}
}
template <typename T>
int AVLTree<T>::calBF(AVLNode<T>* root)
{
if (root == NULL)
{
return 0;
}
else if (root->left == NULL && root->right == NULL)
{
return 0;
}
else if (root->left == NULL)
{
return - root->right->height;
}
else if (root->right == NULL)
{
return root->left->height;
}
else
{
return root->left->height - root->right->height;
}
}
template<typename T>
AVLNode<T>* AVLTree<T>::leftRotate(AVLNode<T>*root)
{
AVLNode<T> *oldRoot = root;
AVLNode<T> *newRoot = root->right;
AVLNode<T> *parent = root->parent;
if (NULL != parent)
{
if (oldRoot->parent->data > oldRoot->data)
{
parent->left = newRoot;
}
else
{
parent->right = newRoot;
}
}
newRoot->parent = parent;
//以上判断旧节点在原先节点的哪个子树上 用新节点取替换
oldRoot->right = newRoot->left;//如果有左子树存在
if (NULL != newRoot->left)
{
newRoot->left->parent = oldRoot;
}
newRoot->left = oldRoot;
oldRoot->parent = newRoot;
oldRoot->height = calHeight(oldRoot);
newRoot->height = calHeight(newRoot);
return newRoot;
//以上将新节点的左子树变成旧节点的右子树,并将旧节点变为新节点的左子树
}
template<typename T>
AVLNode<T>* AVLTree<T>::rightRotate(AVLNode<T>* root)
{
AVLNode<T> *oldRoot = root;
AVLNode<T> *newRoot = root->left;
AVLNode<T> *parent = root->parent;
if (NULL != parent)
{
if (oldRoot->parent->data > oldRoot->data)//判断旧节点其父节点的左右节点
{
parent->left = newRoot;
}
else
{
parent->right = newRoot;
}
}
newRoot->parent = parent;
oldRoot->left = newRoot->right;
if (NULL != newRoot->right)
{
newRoot->right->parent = oldRoot;
}
newRoot->right = oldRoot;
oldRoot->parent = newRoot;
newRoot->height = calHeight(newRoot);
oldRoot->height = calHeight(oldRoot);
return newRoot;
}
int main()
{
AVLTree<int>*tree=new AVLTree<int>();
tree->_insert(3);
tree->_insert(2);
tree->_insert(1);
tree->_insert(4);
tree->_insert(5);
tree->_insert(6);
tree->_insert(7);
tree->_insert(10);
tree->_insert(9);
tree->_insert(8);
tree->layerOrder();
return 0;
}
边栏推荐
- VirtualBox虚拟机安装Win10企业版
- C语言-关键字1
- Alibaba cloud lightweight servers open designated ports
- The most important thing at present
- 去掉录屏提醒(七牛云demo)
- 力扣每日一题-第25天-496.下一个更大元素Ⅰ
- Graduation summary of phase 6 of the construction practice camp
- leetcode-201_2021_10_17
- socket(2)
- [product design and R & D collaboration tool] Shanghai daoning provides you with blue lake introduction, download, trial and tutorial
猜你喜欢
Transport layer UDP & TCP
Pattern recognition - 9 Decision tree
Web project deployment
123. the best time to buy and sell shares III
应用实践 | 海量数据,秒级分析!Flink+Doris 构建实时数仓方案
Handwritten RPC the next day -- review of some knowledge
JMeter implementation specifies concurrent loop testing
Intelligent fish tank control system based on STM32 under Internet of things
Football information query system based on C language course report + project source code + demo ppt+ project screenshot
Why are life science enterprises on the cloud in succession?
随机推荐
memcached全面剖析–3. memcached的删除机制和发展方向
Analysis of tcpdump packet capturing kernel code
What does CTO (technical director) usually do?
[camera Foundation (II)] camera driving principle and Development & v4l2 subsystem driving architecture
#国企央企结构化面试#国企就业#墨斗互动就业服务管家
HCIA assessment
leetcode_1365
Handwritten RPC the next day -- review of some knowledge
【Camera基础(二)】摄像头驱动原理和开发&&V4L2子系统驱动架构
suspense组件和异步组件
Auto. JS to realize automatic unlocking screen
LeetCode-513. 找树左下角的值
Functional analysis of ebpf tracepoint
Fuzhou business office of Fujian development and Reform Commission visited the health department of Yurun university to guide and inspect the work
Remove the screen recording reminder (seven cattle cloud demo)
2022国际女性工程师日:戴森设计大奖彰显女性设计实力
Docking of arkit and character creator animation curves
Network layer & IP
OSI and tcp/ip model
BPF_ PROG_ TYPE_ SOCKET_ Filter function implementation