c++ AVL树 插入 删除

AVL树的插入很简单,根据BST树的特性插入之后在回溯的过程中调整即可

AVL树的删除也不是很难,一共有三种情况

第一种是左子树为空(右子树为不为空无所谓)

第二种是右子树为空(此时左子树不为空)

这两种直接用另一半子树覆盖当前节点然后删除再回溯调整树即可

第三种是左右子数都不为空

这个情况首先找到要删除的节点,然后找到比该节点大的节点中最小的一个节点(右子树中最左边的节点),或者比该节点小的节点中最大的一个节点(左子树中最右边的节点),然后交换这两个节点后再删除原节点(此时就变成了上面两种情况的其中一种),之后回溯的时候调整树

至于为什么要找这两个节点,是因为要保证删除之后还是一颗BST树

AVLTree.h

#pragma once

typedef int ElemType;

struct AVLTreeNode {
	ElemType val;
	int height;
	AVLTreeNode * left;
	AVLTreeNode * right;
	AVLTreeNode(const ElemType & _val = ElemType(), const int & _height = int(),
		AVLTreeNode * _left = nullptr, AVLTreeNode * _right = nullptr)
		: val(_val), height(_height), left(_left), right(_right) {}
};

class AVLTree {
public:
	AVLTree(void) { root = nullptr; }
	~AVLTree(void) { clear(root); }

	void insert(const ElemType &);
	void erase(const ElemType &);

	inline void inOrder(void) { inOrder(root); }

private:
	inline AVLTreeNode * rotateRR(AVLTreeNode *);
	inline AVLTreeNode * rotateRL(AVLTreeNode *);
	inline AVLTreeNode * rotateLR(AVLTreeNode *);
	inline AVLTreeNode * rotateLL(AVLTreeNode *);
	AVLTreeNode * insert(AVLTreeNode *, const ElemType &);
	AVLTreeNode * erase(AVLTreeNode *, const ElemType &);
	inline int getHeight(AVLTreeNode *);
	inline void clear(AVLTreeNode *);
	inline void inOrder(AVLTreeNode *);

private:
	AVLTreeNode * root;

};

AVLTree.cpp

包含algorithm头文件是因为要用到max函数(也可以自己写)

#include <algorithm>

#include "AVLTree.h"

void AVLTree::insert(const ElemType & val) {
	root = insert(root, val);
}

void AVLTree::erase(const ElemType & val) {
	root = erase(root, val);
}

inline AVLTreeNode * AVLTree::rotateRR(AVLTreeNode * node) {
	AVLTreeNode * child = node->left;
	AVLTreeNode * rGrandchild = child->right;
	child->right = node;
	node->left = rGrandchild;
	node->height = 1 + std::max(getHeight(node->left), getHeight(node->right));
	child->height = 1 + std::max(getHeight(node), getHeight(child->left));
	return child;
}

inline AVLTreeNode * AVLTree::rotateRL(AVLTreeNode * node) {
	node->right = rotateRR(node->right);
	return rotateLL(node);
}

inline AVLTreeNode * AVLTree::rotateLR(AVLTreeNode * node) {
	node->left = rotateLL(node->left);
	return rotateRR(node);
}

inline AVLTreeNode * AVLTree::rotateLL(AVLTreeNode * node) {
	AVLTreeNode * child = node->right;
	AVLTreeNode * lGrandchild = child->left;
	child->left = node;
	node->right = lGrandchild;
	node->height = 1 + std::max(getHeight(node->left), getHeight(node->right));
	child->height = 1 + std::max(getHeight(node), getHeight(child->right));
	return child;
}

AVLTreeNode * AVLTree::insert(AVLTreeNode * node, const ElemType & val) {
	if (nullptr == node) {
		node = new AVLTreeNode(val);
	}
	else if (node->val < val) {
		node->right = insert(node->right, val);
	}
	else {
		node->left = insert(node->left, val);
	}
	node->height = 1 + std::max(getHeight(node->left), getHeight(node->right));
	if (getHeight(node->left) - getHeight(node->right) >= 2) {
		if (node->left->val < val) {
			node = rotateLR(node);
		}
		else {
			node = rotateRR(node);
		}
	}
	else if (getHeight(node->right) - getHeight(node->left) >= 2) {
		if (node->right->val < val) {
			node = rotateLL(node);
		}
		else {
			node = rotateRL(node);
		}
	}
	return node;
}

AVLTreeNode * AVLTree::erase(AVLTreeNode * node, const ElemType & val) {
	if (nullptr == node) {
		return nullptr;
	}
	if (val == node->val) {
		if (nullptr == node->left) {
			AVLTreeNode * tmp = node;
			node = node->right;
			delete tmp;
			return node;
		}
		else if (nullptr == node->right) {
			AVLTreeNode * tmp = node;
			node = node->left;
			delete tmp;
			return node;
		}
		else {
			AVLTreeNode * tmp = node->right;
			while (tmp->left) {
				tmp = tmp->left;
			}
			node->val = tmp->val;
			node->right = erase(node->right, tmp->val);
		}
	}
	else if (node->val < val) {
		node->right = erase(node->right, val);
	}
	else {
		node->left = erase(node->left, val);
	}
	node->height = 1 + std::max(getHeight(node->left), getHeight(node->right));
	if (getHeight(node->left) - getHeight(node->right) >= 2) {
		if (getHeight(node->left->left) > getHeight(node->left->right)) {
			node = rotateLR(node);
		}
		else {
			node = rotateRR(node);
		}
	}
	else if (getHeight(node->right) - getHeight(node->left) >= 2) {
		if (getHeight(node->right->right) > getHeight(node->right->left)) {
			node = rotateLL(node);
		}
		else {
			node = rotateRL(node);
		}
	}
	return node;
}

inline int AVLTree::getHeight(AVLTreeNode * node) {
	return nullptr == node ? -1 : node->height;
}

inline void AVLTree::inOrder(AVLTreeNode * node) {
	if (nullptr == node) {
		return;
	}
	inOrder(node->left);
	// output
	inOrder(node->right);
}

inline void AVLTree::clear(AVLTreeNode * node) {
	if (nullptr != node) {
		clear(node->left);
		clear(node->right);
		delete node;
		node = nullptr;
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章