天天看点

数据结构-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;
}









           

继续阅读