栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

AVL二叉搜索树的插入算法

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

AVL二叉搜索树的插入算法

平衡AVL二叉搜索树的插入自平衡算法
  • AVL树
  • AVL树节点定义
  • 平衡方式
    • LL形
    • LR形
    • RR形
    • RL形
  • 完整插入代码

AVL树

AVL 树是一种平衡二叉树,得名于其发明者的名字( Adelson-Velskii 以及 Landis)。
平衡二叉树递归定义如下:

  • 什么是二叉搜索树
    任一结点 小于 其左子树的所有结点小于 其右子树的所有结点;
    结点的左右子树,也是二叉排序树;

  • 什么是AVL树
    搜索二叉树的每个结点的左、右子树高度之差的绝对值不超过1.
    同时引入平衡因子的概念,即:结点的平衡因子= 右子树高度 – 左子树高度

AVL树节点定义

节点包括:

AVLTreeNodeType
val(节点值)int
bf(平衡因子)int
leftTree(左子树)AVLTreeNode*
leftTree(右子树)AVLTreeNode*

定义如下:

struct AVLTreeNode
{
	int val;					// 节点值
	int bf;						// 平衡因子
	AVLTreeNode* leftTree;		// 左子树
	AVLTreeNode* rightTree;		// 右子树
	AVLTreeNode() :val(0), bf(0), leftTree(NULL), rightTree(NULL) {}
	AVLTreeNode(int valable) :val(valable), bf(0), leftTree(NULL), rightTree(NULL) {}
	AVLTreeNode(int valable, int be, AVLTreeNode* lf, AVLTreeNode* rf) :val(valable), bf(be), leftTree(lf), rightTree(rf) {}
	AVLTreeNode* setAVLTree(vector nums);			// 插入平衡算法
};
平衡方式 LL形
  • 不平衡原因:新结点插入到A的左子女的左子树中导致不平衡

算法:

void rotateLL(AVLTreeNode*& root) {
	AVLTreeNode* currL = root;
	root = currL->rightTree;
	currL->rightTree = root->leftTree;
	root->leftTree = currL;
	root->bf = currL->bf = 0;
}

图示:

LR形
  • 不平衡原因:新结点插入到A的右子女的右子树中导致不平衡

算法示例:

void rotateRR(AVLTreeNode*& root) {
	AVLTreeNode* curr = root;
	root = curr->leftTree;
	curr->leftTree = root->rightTree;
	root->rightTree = curr;
	root->bf = curr->bf = 0;
}

图示过程:

RR形
  • 不平衡原因:新结点插入到A的左子女的右子树中导致不平衡

算法示例:

void rotateLR(AVLTreeNode*& root) {
	AVLTreeNode* currL = root->leftTree;
	AVLTreeNode* currR = root;
	root = currL->rightTree;
	currL->rightTree = root->leftTree;
	root->leftTree = currL;
	if (root->bf <= 0)currL->bf = 0;
	else
		currL->bf = -1;

	currR->leftTree = root->rightTree;
	root->rightTree = currR;
	if (root->bf == -1)
		currR->bf = 1;
	else
		currR->bf = 0;
	root->bf = 0;
}

图示过程:

RL形
  • 不平衡原因:新结点插入到A的右子女的左子树中导致不平衡

算法示例:

void rotateRL(AVLTreeNode*& root) {
	AVLTreeNode* currL = root;
	AVLTreeNode* currR = currL->rightTree;
	root = currR->leftTree;
	currL->rightTree = root->leftTree;
	root->leftTree = currL;
	if (root->bf == 1)
		currL->bf = -1;
	else
		currL->bf = 0;
	currR->leftTree = root->rightTree;
	root->rightTree = currR;
	if (root->bf >= 0)
		currR->bf = 0; else
		currR->bf = 1;
	root->bf = 0;
}

图示过程:

完整插入代码

AVLTreeNode.h

#pragma once
#ifndef AVLTREENODE_H
#define AVLTREENODE_H
#include 
#include 
using namespace std;
class AVLTreeNode
{
public:
	int val;
	int bf;		// 平衡因子
	AVLTreeNode* leftTree;
	AVLTreeNode* rightTree;
	AVLTreeNode() :val(0), bf(0), leftTree(NULL), rightTree(NULL) {}
	AVLTreeNode(int valable) :val(valable), bf(0), leftTree(NULL), rightTree(NULL) {}
	AVLTreeNode(int valable, int be, AVLTreeNode* lf, AVLTreeNode* rf) :val(valable), bf(be), leftTree(lf), rightTree(rf) {}
	AVLTreeNode* setAVLTree(vector nums);
};
#endif // !AVLTREENODE_H

AVLTreeNode.cpp

#include "AVLTreeNode.h"
#include 
#include 
#include 
AVLTreeNode* AVLTreeNode::setAVLTree(vector nums)
{
	AVLTreeNode* curr_fa = NULL, *root, *curr_ch;
	if (nums.empty())return NULL;
	root = new AVLTreeNode(nums[0]);
	curr_ch = root;
	stackset_way_save;
	for (int i = 1; i < nums.size(); i++) {
		while (curr_ch)			// 查找应该插入的位置
		{
			if (nums[i] == curr_ch->val) {
				break;
				continue;
			}
			set_way_save.push(curr_ch);
			if (nums[i] < curr_ch->val)curr_ch = curr_ch->leftTree;
			else curr_ch = curr_ch->rightTree;
		}
		AVLTreeNode* node = new AVLTreeNode(nums[i]);
		curr_ch = set_way_save.top();
		if (node->val < curr_ch->val)
			curr_ch->leftTree = node;
		else
			curr_ch->rightTree = node;
		while (!set_way_save.empty()) {
			curr_ch = set_way_save.top();
			set_way_save.pop();
			if (curr_ch->leftTree == node)
				curr_ch->bf--;
			else
				curr_ch->bf++;
			if (curr_ch->bf == 0)break;
			else if (curr_ch->bf == 1 || curr_ch->bf == -1) {
				node = curr_ch;
			}
			else
			{
				if (curr_ch->bf < 0) {
					if (node->bf < 0)
						rotateRR(curr_ch);
					else
						rotateLR(curr_ch);
				}
				else {
					if (node->bf < 0)
						rotateRL(curr_ch);
					else
						rotateLL(curr_ch);
				}
				break;
			}
		}
	}
	return root;
}
void rotateLL(AVLTreeNode*& root) {
	AVLTreeNode* currL = root;
	root = currL->rightTree;
	currL->rightTree = root->leftTree;
	root->leftTree = currL;
	root->bf = currL->bf = 0;
}
void rotateRR(AVLTreeNode*& root) {
	AVLTreeNode* curr = root;
	root = curr->leftTree;
	curr->leftTree = root->rightTree;
	root->rightTree = curr;
	root->bf = curr->bf = 0;
}
void rotateLR(AVLTreeNode*& root) {
	AVLTreeNode* currL = root->leftTree;
	AVLTreeNode* currR = root;
	root = currL->rightTree;
	currL->rightTree = root->leftTree;
	root->leftTree = currL;
	if (root->bf <= 0)currL->bf = 0;
	else
		currL->bf = -1;

	currR->leftTree = root->rightTree;
	root->rightTree = currR;
	if (root->bf == -1)
		currR->bf = 1;
	else
		currR->bf = 0;
	root->bf = 0;
}
void rotateRL(AVLTreeNode*& root) {
	AVLTreeNode* currL = root;
	AVLTreeNode* currR = currL->rightTree;
	root = currR->leftTree;
	currL->rightTree = root->leftTree;
	root->leftTree = currL;
	if (root->bf == 1)
		currL->bf = -1;
	else
		currL->bf = 0;
	currR->leftTree = root->rightTree;
	root->rightTree = currR;
	if (root->bf >= 0)
		currR->bf = 0; else
		currR->bf = 1;
	root->bf = 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/917444.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号