平衡二叉树AVL (用面向对象编程C++实现)

avl.h

#pragma once
#include<iostream>
using namespace std;

class AVLTree {
private:
	class AVLNode {  //内部类,AVL的结点
	public:
		int val;
		AVLNode* left;
		AVLNode* right;
		int height;   //表示该结点所在的高度
	public:
		AVLNode();
		AVLNode(int e);
	};

private:
	void createTree();
	void releaseTree(AVLNode*);  //后序遍历释放AVL树
	void LRotate(AVLNode*&);  //左旋
	void RRotate(AVLNode*&);  //右旋
	void showing(AVLNode*) const;  //前序遍历
	int h(AVLNode*) const;  //获取结点的高度
	AVLNode* insertNode(AVLNode*&,int);
	AVLNode* eraseNode(AVLNode*&, int e);
	int getBalance(AVLNode*);   //获取平衡因子
	void inOrdering(AVLNode*);  //中序遍历
public:
	AVLNode* root;
	int count;
	AVLTree(); 
	~AVLTree(); 
	void insert(int e);
	void erase(int e);
	void show();
	void inOrder();
	int getHeight();
};

avl.cpp

#include "AVLTree.h"

AVLTree::AVLNode::AVLNode(){
	val = 0;
	left = right = nullptr;
	height = 1; 
}

AVLTree::AVLNode::AVLNode(int e){
	val = e;
	left = right = nullptr;
	height = 1;
}

void AVLTree::createTree(){
	this->root = nullptr;
	int count = 0;
}

//后序遍历释放AVL
void AVLTree::releaseTree(AVLNode* r){
	if (r) {
		releaseTree(r->left);
		releaseTree(r->right);
		delete r;
	}
}

void AVLTree::LRotate(AVLNode*& p){
	AVLNode* R = p->right;
	p->right = R->left;
	R->left = p;
	p->height = max(h(p->left), h(p->right)) + 1;
	R->height = max(h(R->left), h(R->right)) + 1;
	p = R;
}

void AVLTree::RRotate(AVLNode*& p){
	AVLNode* L = p->left;
	p->left = L->right;
	L->right = p;
	p->height = max(h(p->left), h(p->right)) + 1;
	L->height = max(h(L->left), h(L->right)) + 1;
	p = L;
}

void AVLTree::showing(AVLNode* n) const{
	if (n) {
		cout << n->val ;
		if (n->left || n->right) {
			cout << '(';
			if (n->left) {
				showing(n->left);
			}
			if (n->right) {
				cout << ',';
				showing(n->right);
			}
			cout << ')';
		}
	}
}

int AVLTree::h(AVLNode* n) const{
	if (n) {
		return n->height;
	}
	return 0;
}

AVLTree::AVLNode* AVLTree::insertNode(AVLNode*& node,int e){
	if (node == nullptr) {
		//创建新节点
		AVLNode* new_node = new AVLNode(e);
		count++;
		return new_node;
	}

	//这是 递 的过程
	if (e < node->val) {
		node->left = insertNode(node->left, e);
	}
	else if (e > node->val) {
		node->right = insertNode(node->right, e);
	}
	else {
		return node;
	}

	//这是 归 的过程
	//需要判断 归 的结果是否失衡
	node->height = max(h(node->left), h(node->right)) + 1;

	//获取平衡因子
	int balance = getBalance(node);

	if (balance > 1) {  //说明出现左失衡,则需要判断是LL还是LR
		if (e > node->left->val) {  //出现了 LR
			LRotate(node->left);
		}
		RRotate(node);
	}
	else if (balance < -1) { //说明出现右失衡,则需要判断是RR还是RL
		if (e < node->right->val) {  //出现了 RL
			RRotate(node->right);
		}
		LRotate(node);
	}

	//将旋转后的结点return 
	return node;
}

AVLTree::AVLNode* AVLTree::eraseNode(AVLNode*& node, int e){
	if (node == nullptr) {  //说明树为空或者找不到值为e的结点
		return nullptr;
	}

	//这是 递 的过程
	if (e < node->val) {
		node->left = eraseNode(node->left, e);
	}
	else if (e > node->val) {
		node->right = eraseNode(node->right, e);
	}
	else {  //说明找到了值为e的节点
		AVLNode* tmp = nullptr;

		//判断e节点的度数
		if (node->left == nullptr || node->right == nullptr) { //度为0或1
			tmp = node->left ? node->left : node->right;
			if (tmp==nullptr) { //度为0
				delete node;  //直接删除
				this->count--;
				return nullptr;
			}

			//度为1
			//进行矛盾转移,从node转为tmp
			node->val = tmp->val;
			node->left = tmp->left;
			node->right = tmp->right;
			delete tmp;
			this->count--;
		}
		else {//度为2
			tmp = node->left;

			//搜索以node为根的左子树的最大值tmp->val
			while (tmp->right) { 
				tmp = tmp->right;
			}
			node->val = tmp->val;   //将最大值赋值给node
			tmp->val = e;  //将e赋值给tmp
			node->left = eraseNode(node->left, e);  //删除tmp
		}
	}

	//这是 归 的过程
	//跟插入时类似,不赘述
	//思路是判断是否失衡,然后旋转
	node->height = max(h(node->left), h(node->right)) + 1;
	int balance = getBalance(node);
	if (balance > 1) {
		if (getBalance(node->left) < 0) {
			LRotate(node->left);
		}
		RRotate(node);
		return node;
	}
	else if (balance < -1) {
		if (getBalance(node->right) > 0) {
			RRotate(node->right);
		}
		LRotate(node);
		return node;
	}
	return node;
}

int AVLTree::getBalance(AVLNode* node){
	if (node) {
		return h(node->left) - h(node->right);
	}
	return 0;
}

void AVLTree::inOrdering(AVLNode* n){
	if (n) {
		inOrdering(n->left);
		cout << n->val << ' ';
		inOrdering(n->right);
	}
}

AVLTree::AVLTree(){
	createTree();
}

AVLTree::~AVLTree(){
	releaseTree(root);
}

void AVLTree::insert(int e){
	if (root == nullptr) {
		AVLNode* node = new AVLNode(e);
		count++;
		root = node;
		return;
	}
	root=insertNode(root, e);
}

void AVLTree::erase(int e){
	if (root) {
		root = eraseNode(root, e);
	}
}

void AVLTree::show(){
	showing(root);
}

void AVLTree::inOrder(){
	inOrdering(root);
}

int AVLTree::getHeight(){
	return h(root);
}

main.cpp

#include "AVLTree.h"

void test() {
	int a[] = { 4,60,70,33,80,90,55,100,110,120,113,126,127 };
	AVLTree t;
	for (auto i : a) {
		t.insert(i);
	}
	t.show();
	cout << endl;
	t.erase(4);
	t.erase(126);
	t.erase(33);
	t.erase(55);
	t.erase(110);
	t.erase(100);
	t.erase(120);
	t.erase(113);
	t.erase(127);
	t.erase(60);
	t.erase(70);
	t.erase(80);
	t.erase(90);
	t.show();
}

int main() {
	test();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值