数据结构——实现key为int类型的AVL树

AVL

AVL在计算机科学中最先发明的自平衡二叉树,得名于它的发明者G.M. Adelson-Velsky, E.M. Landis。

主要特点:AVL树种任何节点的两个子树的高度最大差别为1。

为了保持该特点,AVL可以在进行插入或删除时,采用四种方式进行旋转,分别是LL, LR, RR, RL。

说明

1.该代码没有采用模板的形式实现,采用的key为int类型。事实上,任何能够进行比较大小的类,在实现了比较函数之后,都可以应用到AVL中;

2.删除逻辑上有一点瑕疵,采用的是替换key的方式,不是替换node;

3.该代码没有经过大数据集的测试,欢迎读者测试指正;

4.删除逻辑有部分借鉴自该博客

5.关于AVL的介绍网上有很多,这里不介绍了。

代码

//============================================================================
// Name        : hello.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <cstring>

#ifndef NULL
#define NULL   ((void *) 0)
#endif

using namespace std;

// AVL node
struct AVLNode{
	AVLNode* left;                //  左节点
	AVLNode* right;               //  右节点
	int key;                      //  键值  整数
	int height;                   //  高度
	int symm;                     //  平衡
	AVLNode(int key){
		this->left = NULL;
		this->right = NULL;
		this->height = 0;
		this->symm = 0;
		this->key = key;
	}
};

//  AVL tree
//  unique key tree
class AVLTree{
	private:
		AVLNode*  root;
		int insertIter(AVLNode* current, AVLNode* newNode);
		void switchOp(AVLNode* current, int flag, int childDir);
		void updateNode(AVLNode* node);
		void findOperator(AVLNode**& dir, AVLNode* node, int flag);
		void prePrint(AVLNode* node);
		void inPrint(AVLNode* node);
		void posPrint(AVLNode* node);
		void LL(AVLNode* current, int flag);
		void LR(AVLNode* current, int flag);
		void RL(AVLNode* current, int flag);
		void RR(AVLNode* current, int flag);
		int remove(AVLNode* current, int key);
		int findMax(AVLNode* node);
		int findMin(AVLNode* node);
		void freeNodes(AVLNode* node);
	public:
		AVLTree();
		~AVLTree();
		void insert(int key);                  //  插入
		void prePrint();                       //  前序遍历
		void inPrint();                        //  中序遍历
		void posPrint();                       //  后序遍历
		void remove(int key);                  //  删除
};

/************************init and free**********************************/
AVLTree::AVLTree(){
	this->root = NULL;
}

AVLTree::~AVLTree(){
	freeNodes(root);
}
void AVLTree::freeNodes(AVLNode* node){
	if(!node){
		return;
	}else{
		freeNodes(node->left);
		freeNodes(node->right);
		delete node;
	}
}

/***************************insert*************************************/
void AVLTree::insert(int key){
	AVLNode* newNode = new AVLNode(key);
	if(!root){
		root = newNode;
	}else{
		int flag = insertIter(root, newNode);
		switchOp(root, flag, 2);
	}
}
int AVLTree::insertIter(AVLNode* current, AVLNode* newNode){
	int returnValue;                       // 0 for left, 1 for right
	int dir;                               // 0 for left, 1 for right, 2 for LL, 4 for LR, 6 for RR, 8 for RL
	if(newNode->key < current->key){       // 分向左边
		if(current->left){
			dir = insertIter(current->left, newNode);
			switchOp(current, dir, 0);
		}else{
			current->left = newNode;
		}
		returnValue = 0;                   // 告诉上级, 下级去哪了
	}else{
		if(current->right){
			dir = insertIter(current->right, newNode);
			switchOp(current, dir, 1);
		}else{
			current->right = newNode;
		}
		returnValue = 1;
	}

	// 更新 节点 信息
	updateNode(current);
	if(current->symm > 1){                 //  L
		if(dir==0){
			returnValue = 2;               //  LL
		}else if(dir==1){
			returnValue = 4;               //  LR
		}
	}else if(current->symm <-1){           //  R
		if(dir==0){
			returnValue = 8;               //  RL
		}else if(dir==1){
			returnValue = 6;               //  RR
		}
	}
	return returnValue;
}

/****************************remove*************************************/
void AVLTree::remove(int key){
	if(!root){
		return ;
	}else{
		int flag = remove(root, key);
		switchOp(root, flag, 2);
	}
}
int AVLTree::remove(AVLNode* current, int key){
	if(!current){
		return -2;
	}else{
		int dir;                                      // -1 for 子节点被删, 0 for 左边较高     1 for 右边较高 ,   2 for  LL  ........
		if(current->key > key){                       //  左子树
			dir = remove(current->left, key);
			if(dir == -1)
				current->left = NULL;
			else switchOp(current, dir, 0);
		}else if(current->key < key){                 //  右子树
			dir = remove(current->right, key);
			if(dir == -1)
				current->right = NULL;
			else switchOp(current, dir, 2);
		}else{                                        //  该节点
			if(!current->left && !current->right){    //  两个子树为空
				delete current;                       //  删除
				return -1;
			}else{
				if(current->symm > 0){                                  //  左子树较高
					int leftMaxKey = findMax(current->left);
					current->key = leftMaxKey;
					dir = remove(current->left, leftMaxKey);
					if(dir == -1)
						current->left = NULL;
					else switchOp(current, dir, 1);
				}else{
					int rightMinKey = findMin(current->right);
					current->key = rightMinKey;
					dir = remove(current->right, rightMinKey);
					if(dir == -1)
						current->right = NULL;
					else switchOp(current, dir, 2);
				}
			}
		}

		// 更新节点 信息
		updateNode(current);
		int returnValue;
		if(current->symm > 1){                 //  L
			if(current->left->symm>0){
				returnValue = 2;               //  LL
			}else {
				returnValue = 4;               //  LR
			}
		}else if(current->symm <-1){           //  R
			if(current->right->symm<0){
				returnValue = 6;               //  RR
			}else {
				returnValue = 8;               //  RL
			}
		}
		return returnValue;
	}
}

/*****************************common*************************************/
int AVLTree::findMax(AVLNode* node){
	AVLNode* tmp = node;
	while(tmp->right){
		tmp = tmp->right;
	}
	return tmp->key;
}

int AVLTree::findMin(AVLNode* node){
	AVLNode* tmp = node;
	while(tmp->left){
		tmp = tmp->left;
	}
	return tmp->key;
}

void AVLTree::updateNode(AVLNode* node){
	int leftHeight = node->left ? node->left->height+1:0;
	int rightHeight = node->right ? node->right->height+1:0;
	node->height = leftHeight > rightHeight ? leftHeight:rightHeight;
	node->symm = leftHeight - rightHeight;
}

void AVLTree::switchOp(AVLNode* current, int flag, int childDir){
	switch(flag){
		case 2:
			LL(current, childDir);
			break;
		case 4:
			LR(current, childDir);
			break;
		case 6:
			RR(current, childDir);
			break;
		case 8:
			RL(current, childDir);
			break;
		default:
			break;
	}
}

void AVLTree::findOperator(AVLNode**& dir, AVLNode* node, int flag){
	switch(flag){
			case 0:
				dir = &(node->left);
				break;
			case 1:
				dir = &(node->right);
				break;
			case 2:
				dir = &(root);
				break;
			default:
				break;
		}
}


/***********************operation**********************************/
//
//             A
//            /                     B
//           B        ----->       / \
//          / \                   C   A
//         C   D                     /
//                                  D
//
void AVLTree::LL(AVLNode* current, int flag){
	AVLNode* (*dir);
	findOperator(dir, current, flag);

	AVLNode* A = *dir;
	AVLNode* B = A->left;
	AVLNode* D = B->right;
	*dir = B;
	B->right = A;
	A->left = D;
	updateNode(A);
	updateNode(B);
}

//
//            A
//           /                    C
//          B      ------>       / \
//           \                  /   \
//            C                B     A
//           / \                \   /
//          D   E                D E
//
//
void AVLTree::LR(AVLNode* current, int flag){
	AVLNode** dir;
	findOperator(dir, current, flag);

	AVLNode* A = *dir;
	AVLNode* B = A->left;
	AVLNode* C = B->right;
	AVLNode* D = C->left;
	AVLNode* E = C->right;

	*dir = C;
	C->left = B;
	C->right = A;
	B->right = D;
	A->left = E;
	updateNode(B);
	updateNode(A);
	updateNode(C);
}

//
//         A
//          \                      C
//           B  -------->         / \
//          /                    /   \
//         C                    A     B
//        / \                    \   /
//       D   E                    D E
//
void AVLTree::RL(AVLNode* current, int flag){
	AVLNode** dir;
	findOperator(dir, current, flag);

	AVLNode* A = *dir;
	AVLNode* B = A->right;
	AVLNode* C = B->left;
	AVLNode* D = C->left;
	AVLNode* E = C->right;

	*dir = C;
	C->left = A;
	C->right = B;
	B->left = E;
	A->right = D;
	updateNode(B);
	updateNode(A);
	updateNode(C);
}

//
//      A
//       \                        B
//        B        ----->        / \
//       / \                    A   C
//      D   C                    \
//                                D
//
void AVLTree::RR(AVLNode* current, int flag){
	AVLNode** dir;
	findOperator(dir, current, flag);
	AVLNode* A = *dir;
	AVLNode* B = A->right;
	AVLNode* D = B->left;
	*dir = B;
	B->left = A;
	A->right = D;
	updateNode(A);
	updateNode(B);
}

/***************************printer***********************************/
void AVLTree::prePrint(){
	prePrint(root);
	cout << endl;
}

void AVLTree::prePrint(AVLNode* node){
	if(!node){
		return;
	}else{
		cout << node->key <<" ";
		prePrint(node->left);
		prePrint(node->right);
	}
}

void AVLTree::inPrint(){
	inPrint(root);
	cout << endl;
}

void AVLTree::inPrint(AVLNode* node){
	if(!node){
		return;
	}else{
		inPrint(node->left);
		cout << node->key <<" ";
		inPrint(node->right);
	}
}

void AVLTree::posPrint(){
	posPrint(root);
	cout << endl;
}

void AVLTree::posPrint(AVLNode* node){
	if(!node){
		return;
	}else{
		posPrint(node->left);
		posPrint(node->right);
		cout << node->key <<" ";
	}
}

/***************************main**********************************/
int main() {
	int num;
	cin >> num ;
	AVLTree tree ;
	int value;
	for(int i = 0; i < num; i++){
		cin >> value;
		tree.insert(value);
	}
	// remove operation
	cin >> num;
	for(int i = 0; i < num; i++){
		cin >> value;
		tree.remove(value);
	}
	tree.prePrint();
	tree.inPrint();
	tree.posPrint();
	return 0;
}

运行

节点数目:16
节点顺序:3 2 1 4 5 6 7 16 15 14 13 12 11 10 8 9 
删除数目:3
删除顺序:6 5 1
前序遍历:11 7 3 4 9 8 10 13 12 15 14 16 
中序遍历:3 4 7 8 9 10 11 12 13 14 15 16 
后序遍历:4 3 8 10 9 7 12 14 16 15 13 11 

    原文作者:AVL树
    原文地址: https://blog.csdn.net/jeffery_gong/article/details/52035849
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞