天天看點

資料結構-AVL樹

為什麼需要AVL樹,以樹的結構插入或删除大量随機資料時,有可能會導緻樹的一邊輕一邊重, 例如極端情況插入依次123456時,樹就與連結清單無異了,Ologn的查找效率也變成了On;

AVL樹的特性:左右子樹高度差最大為1,為了維持這個特性,在插入和删除操作時就需要旋轉;

旋轉規則:當插入位置為對左兒子的左子樹進行插入則左單旋,左兒子的右子樹時左雙旋, 右兒子則鏡像;

#include <iostream>
#include <queue>
#include <utility>

using namespace std;
template<typename T>
class AVLTree{
public:
	AVLTree();
	~AVLTree();
	AVLTree(const AVLTree &t);
	AVLTree& operator=(const AVLTree &t);

	void insert(const T &t);
	void remove(const T &t);
	void clear();
	bool contains(const T &t) const;
	bool empty() const;

	void inorder();
	void levelorder();

private:
    struct Node{
        T val;
        int height;
        Node *left;
        Node *right;
        Node(T x, Node *l = NULL, Node *r = NULL, int h = 0)
			: val(x), height(h), left(l), right(r){};
    };
    Node *root;

	Node *&findMax(Node *&k);
	Node *&findMin(Node *&k);

	int height(Node *&k) const;
	void rotateWithLeft(Node *&k1);
	void doubleWithLeft(Node *&k3);
	void rotateWithRight(Node *&k2);
	void doubleWithRight(Node *&k3);

	void insert(const T &t, Node *&k);
	void remove(const T &t, Node *&k);
	void clear(Node *&k);
	bool contains(const T &t, Node *const &k) const;
	void inorder(Node *&k);

	Node* copy_tree(Node *t);
};
/***構造***/
template<typename T>
AVLTree<T>::AVLTree()
 : root(NULL)
 {

 }
/***析構****/
template<typename T>
AVLTree<T>::~AVLTree()
{
	clear();
}
/**拷貝構造****/
template<typename T>
AVLTree<T>::AVLTree(const AVLTree &t)
{
	root = copy_tree(t.root);
}
/***指派重載****/
template<typename T>
AVLTree<T>& AVLTree<T>::operator=(const AVLTree &t)
{
	if(this != &t)
	{
		AVLTree<T> tmp(t);
		swap(root, tmp.root);
	}
	return *this;
}
/****插入函數使用者接口***/
template<typename T>
void AVLTree<T>::insert(const T &t)
{
	insert(t, root);
}
/****删除函數使用者接口****/
template<typename T>
void AVLTree<T>::remove(const T &t)
{
	remove(t, root);
}
/***清空樹***/
template<typename T>
void AVLTree<T>::clear()
{
	clear(root);
}
/***判斷是否包含某元素***/
template<typename T>
bool AVLTree<T>::contains(const T &t) const
{
	return contains(t, root);
}
/***判空****/
template<typename T>
bool AVLTree<T>::empty() const
{
	return root == NULL;
}
/***中序周遊****/
template<typename T>
void AVLTree<T>::inorder()
{
	inorder(root);
}
/***層序周遊****/
template<typename T>
void AVLTree<T>::levelorder()
{
    if(!root)
        return ;
	int curlevel = 0;
	queue<pair<Node *, int> > q;
	q.push(make_pair(root, curlevel));
	while(!q.empty())
	{
		pair<Node*, int> tmp = q.front();
		q.pop();
		if(tmp.second > curlevel)
		{
			cout << endl;
			curlevel = tmp.second;
		}
		cout << tmp.first->val << " ";
		if(tmp.first->left)
			q.push(make_pair(tmp.first->left, curlevel+1));
		if(tmp.first->right)
			q.push(make_pair(tmp.first->right, curlevel+1));
	}
}
/***傳回最大值節點即最右節點****/
template<typename T>
typename AVLTree<T>::Node*& AVLTree<T>::findMax(Node *&k)
{
	if(k->right)
		return findMax(k->right);
	else
		return k;
}
/****傳回最小值節點即最左節點****/
template<typename T>
typename AVLTree<T>::Node*& AVLTree<T>::findMin(Node *&k)
{
	if(k->left)
		return findMax(k->left);
	else
		return k;
}
/****傳回節點高度NULL為-1****/
template<typename T>
int AVLTree<T>::height(Node *&k) const
{
	return k==NULL ? -1 : k->height;
}
/****左單旋即逆時針旋轉****/
template<typename T>
void AVLTree<T>::rotateWithLeft(Node *&k1)
{
	Node *k2 = k1->left;
	k1->left = k2->right;
	k2->right = k1;

	k1->height = max(height(k1->left), height(k1->right))+1;
	k2->height = max(height(k2->left), k1->height)+1;

	k1 = k2;
}
/***左雙旋*****/
template<typename T>
void AVLTree<T>::doubleWithLeft(Node *&k3)
{
	rotateWithRight(k3->left);
	rotateWithLeft(k3);
}
/***右單旋,順時針旋轉****/
template<typename T>
void AVLTree<T>::rotateWithRight(Node *&k2)
{
	Node *k1 = k2->right;
	k2->right = k1->left;
	k1->left = k2;

	k2->height = max(height(k2->left), height(k2->right))+1;
	k1->height = max(height(k1->right), k2->height)+1;

	k2 = k1;
}
/***右雙旋*****/
template<typename T>
void AVLTree<T>::doubleWithRight(Node *&k3)
{
	rotateWithLeft(k3->right);
	rotateWithRight(k3);
}
/****遞歸插入并保持平衡****/
template<typename T>
void AVLTree<T>::insert(const T &t, Node *&k)
{
	if(k == NULL)
		k = new Node(t);
	else if(t < k->val)
	{
		insert(t, k->left);
		if(height(k->left)-height(k->right) == 2)
		{
			if(t < k->left->val)
				rotateWithLeft(k);
			else
				doubleWithLeft(k);
		}
	}
	else if(t > k->val)
	{
		insert(t, k->right);
		if(height(k->right)-height(k->left) == 2)
		{
			if(t > k->right->val)
				rotateWithRight(k);
			else
				doubleWithRight(k);
		}
	}

	k->height = max(height(k->left), height(k->right))+1;
}
/****遞歸删除保持平衡****/
template<typename T>
void AVLTree<T>::remove(const T &t, Node *&k)
{
	if(k == NULL)
		return ;
	else if(t < k->val)
	{
		remove(t, k->left);
		if(height(k->right)-height(k->left) == 2)
		{
			Node *tmp = k->right;
			if(height(tmp->left) <= height(tmp->right))
				rotateWithRight(k);
			else
				doubleWithRight(k);
		}
	}
	else if(t > k->val)
	{
		remove(t, k->right);
		if(height(k->left)-height(k->right) == 2)
		{
			Node *tmp = k->left;
			if(height(tmp->right) <= height(tmp->left))
				rotateWithLeft(k);
			else
				doubleWithLeft(k);
		}
	}
	else{
		if(k->left && k->right)
		{
			if(height(k->left) > height(k->right))
			{
				Node *&tmp = findMax(k->left);
				k->val = tmp->val;
				remove(tmp->val, tmp);
			}
			else{
				Node *&tmp = findMin(k->right);
				k->val = tmp->val;
				remove(tmp->val, tmp);
			}
		}
		else{
			Node *tmp = k;
			k = k->left ? k->left : k->right;
			delete tmp;
		}
	}
}
/**遞歸清空樹***/
template<typename T>
void AVLTree<T>::clear(Node *&k)
{
	if(k)
	{
		clear(k->left);
		clear(k->right);
		delete k;
	}
	k = NULL;
}
/***遞歸檢測是否包含某元素****/
template<typename T>
bool AVLTree<T>::contains(const T &t, Node *const &k) const
{
	if(k == NULL)
		return false;
	else if(t < k->val)
		return contains(t, k->left);
	else if(t > k->val)
		return contains(t, k->right);
	else
		return true;
}
/***中序****/
template<typename T>
void AVLTree<T>::inorder(Node *&t)
{
	if(t)
	{
		inorder(t->left);
		cout << t->val << " ";
		inorder(t->right);
	}
}
/***遞歸深拷貝****/
template<typename T>
typename AVLTree<T>::Node* AVLTree<T>::copy_tree(Node *k)
{
	if(k == NULL)
		return NULL;
	return new Node(k->val, copy_tree(k->left), copy_tree(k->right));
}

int main()
{
    int a[16] = {3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9};
    AVLTree<int> mytree;
    for(auto i : a)
        mytree.insert(i);
    mytree.levelorder();
    cout << endl;
    //mytree.remove(4);
    mytree.remove(6);
    mytree.remove(5);
    mytree.levelorder();
    cout << endl;
    mytree.inorder();
    cout << endl;
    cout << mytree.empty() << endl;
    cout << mytree.contains(8) << endl;
    return 0;
}









           

繼續閱讀