手写数据结构:AVL树
Posted 看,未来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写数据结构:AVL树相关的知识,希望对你有一定的参考价值。
刚开始比较懒,写的不多。代码部分测试,等整个系列写完再完整的测一遍
#include<iostream>
#include<vector>
using namespace std;
class TreeNode {
public:
//这几个数据放做公有的,方便操作
int depth; //深度,这里计算每个结点的深度,通过深度的比较可得出是否平衡
TreeNode* parent; //该结点的父节点,方便操作
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) {}
void setnode(int val) {
this->val = val;
}
void setleft(TreeNode* node) {
this->left = node;
}
void setright(TreeNode* node) {
this->right = node;
}
};
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) {
return left_rotate(right_rotate(root));
}
TreeNode* left_right_rotate(TreeNode* root) {
return right_rotate(left_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);
}
}
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);
}
}
}
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);
}
}
}
};
int main() {
}
以上是关于手写数据结构:AVL树的主要内容,如果未能解决你的问题,请参考以下文章