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;
	}
}

 

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