初心者の数据结构日记 (1) C++ 风格的 AVL树

该文详细介绍了AVL树的插入、删除操作以及平衡旋转(LL旋转、RR旋转、LR旋转、RL旋转)的过程,通过自旋调整以保持树的平衡,同时提供了对树的前序、中序和后序遍历方法。此外,还展示了如何将树转换成链表进行遍历。
摘要由CSDN通过智能技术生成

个人学习心得 :

1.通过构建每种情况下符合avl树特点的失衡状况,可以高效的理解自旋以及自旋后的平衡因子变化。自旋时的关键节点有哪些?那些关节点是怎么位移的?那些关键节点的关键节点子树之间的高度差应该是多少?

2.迭代遍历就是把树放倒,拆分成一个个链表。

#pragma once
template<typename key,typename value>
class Avltree
{
	using Fun = void(*)(value& s);
	struct Node
	{
		Node* L;
		Node* R;
		Node* F;
		key _key;
		value _value;
		int bf;
	};
	struct DNode
	{
		Node* p;
		DNode* Next;
		DNode* Prev;
	};
	class list {
	public:
		DNode* F;
		DNode* R;
		bool empty() {
			return R->Prev == F;
		}
		void push_back(Node* c) {
			DNode* cur = new DNode();
			cur->p = c;
			cur->Prev = R->Prev;
			R->Prev->Next = cur;
			R->Prev = cur;
			cur->Next = R;
		}
		void push_front(Node* c) {
			DNode* cur = new DNode();
			cur->p = c;
			cur->Next = F->Next;
			F->Next->Prev = cur;
			F->Next = cur;
			cur->Prev = F;
		}
		Node* pop_back() {
			Node* c=nullptr;
			if (!empty())
			{
				DNode* cur = R->Prev;
				R->Prev =cur->Prev;
				cur->Prev->Next = R;
				c = cur->p;
				delete cur;
			}
			return c;
		}
		Node* pop_front() {
			Node* c = nullptr;
			if (!empty())
			{
				DNode* cur = F->Next;
				F->Next = cur->Next;
				cur->Next->Prev = F;
				c = cur->p;
				delete cur;
			}
			return c;
		}
		list() {
			F = new DNode();
			R = new DNode();
			R->Next = nullptr;
			R->Prev = F;
			F->Next = R;
			F->Prev = nullptr;
		}
		~list() {
			while (!empty())
				pop_back();
			delete F;
			delete R;
		}
	};
	Node* T;
	value _FALSE;
	bool LL(Node* f);
	bool RR(Node* f);
	bool RL(Node* f);
	bool LR(Node* f);
public:
	bool insert(key k, value v);
	bool Delete(key k);
	int Depth();
	void preorder(Fun fp);
	void inorder(Fun fp);
	void postorder(Fun fp);


	//
	//
	//
	//
	//


	value& operator[](key k) {
		Node* cur = T;
		Node* f = nullptr;
		while (cur != nullptr)
		{
			if (cur->_key == k) {
				return cur->_value;
			}
			else if (k > cur->_key)
			{
				f = cur;
				cur = cur->R;
			}
			else
			{
				f = cur;
				cur = cur->L;
			}
		}
		return _FALSE;
	}
	Avltree():T(nullptr), _FALSE(0) {}
	Avltree(const Avltree<key,value> &base) :T(nullptr), _FALSE(0) {
		if (base.T == nullptr)
			return;
		list q{};
		Node* p = nullptr;
		q.push_back(base.T);
		while (!q.empty())
		{
			p = q.pop_front();
			insert(p->_key, p->_value);
			if (p->L != nullptr) {
				q.push_back(p->L);
			}
			if (p->R != nullptr) {
				q.push_back(p->R);
			}
		}
		_FALSE = base._FALSE;
	}
	~Avltree(){
		list s{};
		Node* cur = T;
		Node* f = nullptr;
		while (cur != nullptr || !s.empty())
		{
			if (cur!=nullptr)
			{
				s.push_back(cur);
				cur = cur->L;
			}
			else
			{
				if (!s.empty()) {
					cur = s.pop_back();
					if (cur->R == nullptr)
					{	
						if (cur->F == nullptr)
						{
							goto _NodeT;
						}
						f = cur->F;
						if (cur == f->R)
						{
							f->R = nullptr;
						}
						else
						{
							f->L = nullptr;
						}
						_NodeT:
						delete cur;
						cur = nullptr;
					}
					else
					{
						s.push_back(cur);
						cur = cur->R;
					}
				}
			}
		}
		T = nullptr;
	}
};

template<typename key, typename value>
void Avltree<key, value> ::preorder(Fun fp) {
	list s{};
	Node* p = T;
	while (p!=nullptr||!s.empty())
	{
		while (p != nullptr) {
			s.push_back(p);
			fp(p->_value);
			p = p->L;
		}
		if (!s.empty()) {
			p = s.pop_back();
			p = p->R;
		}
	}
}

template<typename key, typename value>
void Avltree<key, value> ::inorder(Fun fp) {
	list s{};
	Node* p = T;
	while (p != nullptr || !s.empty())
	{
		while (p != nullptr) {
			s.push_back(p);
			p = p->L;
		}
		if (!s.empty()) {
			p = s.pop_back();
			fp(p->_value);
			p = p->R;
		}
	}
}

template<typename key, typename value>
void Avltree<key, value> ::postorder(Fun fp) {
	list s{};
	Node* cur = T;
	Node* Prev = nullptr;
	while (cur != nullptr || !s.empty())
	{
		if (cur != nullptr) {
			s.push_back(cur);
			cur = cur->L;
		}
		else
		{
			if (!s.empty()) {
				cur = s.pop_back();
				if (cur->R == nullptr || cur->R == Prev) {
					Prev = cur;
					fp(cur->_value);
					cur = nullptr;
				}
				else
				{
					s.push_back(cur);
					cur = cur->R;
				}
			}
		}
	}
}

template<typename key, typename value>
int Avltree<key, value> ::Depth() {
	if (T==nullptr)
	{
		return 0;
	}
	list q{};
	q.push_back(T);
	int front = 0, rear = 1, len = 1,_Depth = -1;
	Node* p = nullptr;
	while (!q.empty())
	{
		p = q.pop_front();
		front++;
		if (p->L != nullptr) {
			q.push_back(p->L);
			rear++;
		}			
		if (p->R != nullptr) {
			q.push_back(p->R);
			rear++;
		}
		if (front == len) {
			_Depth++;
			len = rear;
		}			
	}
	return _Depth;
}

template<typename key, typename value>
bool Avltree<key, value> :: LL(Node* f) {//根节点以左子树为轴向左自旋
	Node* gf = f->F;
	Node* s = f->L;
	Node* sr = s->R;
	s->F = gf;
	if (f == T)
	{
		T = s;
	}
	if (gf != nullptr) {
		if (gf->L == f)
		{
			gf->L = s;
		}
		else
		{
			gf->R = s;
		}
	}
	f->L = sr;
	if (sr !=nullptr)
	{
		sr->F = f;
	}
	f->F = s;
	s->R = f;
	f->bf = 0;
	s->bf = 0;
	return true;
}

template<typename key, typename value>
bool Avltree<key, value> :: RR(Node* f) {//根节点以右子树为轴向右自旋
	Node* gf = f->F;
	Node* s = f->R;
	Node* sl = s->L;
	if (f==T)
	{
		T = s;
	}
	s->F = gf;
	if (gf != nullptr) {
		if (gf->L == f)
		{
			gf->L = s;
		}
		else
		{
			gf->R = s;
		}
	}	
	if (sl != nullptr)
	{
		sl->F = f;
	}
	f->R = sl;
	s->L = f;
	f->F = s;
	f->bf = 0;
	s->bf = 0;
	return true;
}

template<typename key, typename value>
bool Avltree<key, value> :: LR(Node* f) {
	Node* s = f->R;
	Node* sl = s->L;
	int bf = sl->bf;
	LL(s);
	RR(f);
	if (bf == 1)
	{
		s->bf = 0;
		f->bf = -1;
		sl->bf = 0;
	}
	else if (bf == -1)
	{
		s->bf = 1;
		f->bf = 0;
		sl->bf = 0;
	}
	else if(bf == 0) {
		s->bf = 0;
		f->bf = 0;
		sl->bf = 0;
	}
	else
	{
		return false;
	}
	return true;
}

template<typename key, typename value>
bool Avltree<key, value> :: RL(Node* f) {
	Node* s = f->L;
	Node* sr = s->R;
	int bf = sr->bf;
	RR(s);
	LL(f);
	if (bf == 1)
	{
		s->bf = -1;
		f->bf = 0;
		sr->bf = 0;
	}
	else if (bf == -1)
	{
		s->bf = 0;
		f->bf = 1;
		sr->bf = 0;
	}
	else if (bf == 0) {
		s->bf = 0;
		f->bf = 0;
		sr->bf = 0;
	}
	else
	{
		return false;
	}
	return true;
}

template<typename key, typename value>
bool Avltree<key, value>::Delete(key k) {
	Node* f = nullptr;
	Node* cur = T;
	int ibf = 0;
	while (cur != nullptr)
	{
		if (cur->_key == k) {
			break;
		}
		else if (k > cur->_key)
		{
			f = cur;
			cur = cur->R;
		}
		else
		{
			f = cur;
			cur = cur->L;
		}
	}
	if (cur!=nullptr)
	{
        if (cur->L==nullptr&& cur->R!=nullptr)
		{
			if(cur->R !=nullptr)
				cur->R->F = f;
			if (f!=nullptr)
			{
				if (f->L == cur)
				{
					f->L = cur->R;
					ibf = 1;
				}
				else
				{
					f->R = cur->R;
					ibf = -1;
				}
				
			}
			else
			{
				T = cur->R;
			}
		}
		else if (cur->R == nullptr&&cur->L!=nullptr)
		{
			if(cur->L !=nullptr)
				cur->L->F = f;
			if (f!=nullptr)
			{
				if (f->L == cur)
				{
					f->L = cur->L;
					ibf = 1;
				}
				else
				{
					f->R = cur->L;
					ibf = -1;
				}
			}
			else
			{
				T = cur->L;
			}

		}
		else if(cur->R != nullptr && cur->L != nullptr)
		{
			f = cur;
			cur = cur->R;
			while (cur->L!=nullptr)
			{				
				cur = cur->L;
			}
			f->_key = cur->_key;
			f->_value = cur->_value;	
			f = cur->F;
			if (f->L == cur)
			{
				if (cur->R != nullptr) {
					f->L = cur->R;
					cur->R->F = f;
				}
				else {
					f->L = nullptr;
				}
				ibf = 1;
			}
			else
			{
				if (cur->R != nullptr) {
					f->R = cur->R;
					cur->R->F = f;
				}
				else {
					f->R = nullptr;
				}
				ibf = -1;
			}
		}
		else
		{
			if (f!=nullptr)
			{
				if (f->L == cur)
				{
					f->L = nullptr;
					ibf = 1;
				}
				else
				{
					f->R = nullptr;
					ibf = -1;
				}
			}
			else
			{
				T = nullptr;
			}
		}
		delete cur;
		cur = nullptr;
		while (f != nullptr )
		{
			f->bf += ibf;
			if (f->bf == -1 || f->bf == 1)
			{
				break;
			}
			else if (f->bf == 0)
			{

				cur = f;
				f = f->F;
				if (f == nullptr)
				{
					break;
				}
				if (f->L == cur)
				{
					ibf = 1;
				}
				else
				{
					ibf = -1;
				}

			}
			else if (f->bf == -2)
			{
				cur = f->L;
				if (cur->bf == 1)
				{
					RL(f);
					cur = cur->F;
				}
				else if (cur->bf == -1)
				{
					LL(f);
				}
				else
				{
					LL(f);
					f->bf = -1;
					cur->bf = 1;
					break;
				}
				f = cur->F;
				if (f == nullptr)
				{
					break;
				}
				if (f->L == cur)
				{
					ibf = 1;
				}
				else
				{
					ibf = -1;
				}
			}
			else if (f->bf == 2)
			{
				cur = f->R;
				if (cur->bf == 1)
				{
					RR(f);
				}
				else if (cur->bf == -1)
				{
					LR(f);
					cur = cur->F;
				}
				else
				{
					RR(f);
					f->bf = 1;
					cur->bf = -1;
					break;
				}
				f = cur->F;
				if (f == nullptr)
				{
					break;
				}
				if (f->L == cur)
				{
					ibf = 1;
				}
				else
				{
					ibf = -1;
				}
			}
			else
			{
				return false;
			}
		}
		
		return true;
	}
	return false;
}
template<typename key, typename value>
bool Avltree<key, value>::insert(key k, value v) {
	if (T == nullptr)
	{
		T = new Node();
		T->_key = k;
		T->_value = v;
		T->L = nullptr;
		T->R = nullptr;
		T->F = nullptr;
		T->bf = 0;
	}
	else
	{
		Node* f = nullptr;
		Node* cur = T;
		int ibf = 0;
		while (cur != nullptr)
		{
			if (cur->_key == k) {
				return false;
			}
			else if (k > cur->_key)
			{
				f = cur;
				cur = cur->R;
			}
			else
			{
				f = cur;
				cur = cur->L;
			}
		}
		if (k > f->_key)
		{
			f->R = new Node();
			cur = f->R;
			cur->bf = 0;
			cur->L = nullptr;
			cur->R = nullptr;
			cur->_key = k;
			cur->_value = v;
			cur->F = f;
			ibf = 1;
		}
		else
		{
			f->L = new Node();
			cur = f->L;
			cur->bf = 0;
			cur->L = nullptr;
			cur->R = nullptr;
			cur->_key = k;
			cur->_value = v;
			cur->F = f;
			ibf = -1;
		}
		while ( f != nullptr )
		{
			f->bf += ibf;
			if (f->bf == 0)
			{
				break;
			}
			else if (f->bf == -1 || f->bf == 1)
			{

				cur = f;
				f = f->F;
				if (f==nullptr)
				{
					break;
				}
				if (f->L == cur)
				{
					ibf = -1;
				}
				else
				{
					ibf = 1;
				}
				
			}
			else if ( f->bf == -2 )
			{
				if (cur->bf == 1)
				{
					RL(f);
				}
				else
				{
					LL(f);
				}
				break;
			}
			else if (f->bf == 2)
			{
				if (cur->bf == 1)
				{
					RR(f);
				}
				else
				{
					LR(f);
				}
				break;
			}
			else
			{
				return false;
			}
		}
	}
	return true;
}


如有BUG,还请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值