tinystl实现(第二十三步:avl树实现)

39 篇文章 4 订阅
28 篇文章 36 订阅

经过长时间的学习终于可以开始tinystl的仿(chao)写工作了,本文参考了这位大神的github,坦白讲我只是补充了注释,因为tinystl的代码真的非常经典而我又没什么这种大型项目的经验,所以只能这样做,不过相信能够有助于大家的学习
#强烈建议按顺序阅读本专栏
avl树的构成和bst树的构成有很多相同之处,无非就是多了旋转(查看这篇博客了解)
.h文件

#pragma once
#ifndef _AVL_TREE_H_
#define _AVL_TREE_H_

#include "Allocator.h"
#include "Iterator.h"
#include "Stack.h"
#include "String.h"

#include <set>

namespace mySTL {
	namespace Detail {
		template<class T>
		class avl_iter;
	}
	//class of avl tree
	template<class T>
	class avl_tree {
	private:
		template<class T>
		friend class Detail::avl_iter;
	private:
		struct node {
			T data_;
			node *left_, *right_;
			size_t height_;
			typedef T value_type;
			explicit node(T d = T(), node *l = 0, node *r = 0, size_t h = 1)
				:data_(d), left_(l), right_(r), height_(h) {}
		};
		typedefmySTL::allocator<node> dataAllocator;
	public:
		typedef T value_type;
		typedef Detail::avl_iter<node> const_iterator;
		typedef const T& const_reference;
		typedef size_t size_type;
	private:
		node *root_;
		size_t size_;
	public:
		avl_tree() :root_(0), size_(0) {}
		avl_tree(const avl_tree&) = delete;
		avl_tree& operator = (const avl_tree&) = delete;
		~avl_tree();

		void insert(const T& val);
		template<class Iterator>
		void insert(Iterator first, Iterator last);
		void erase(const T& val);

		size_t height()const { return getHeight(root_); }
		size_t size()const { return size_; }
		bool empty()const { return root_ == 0; }
		const_iterator root()const { return const_iterator(root_, this); }

		const_iterator cbegin()const { return find_min(); }
		const_iterator cend()const { return const_iterator(0, this); }

		const_iterator find_min()const;
		const_iterator find_max()const;
		const_iterator find(const T& val)const;

		void print_preorder(const string& delim = " ", std::ostream& os = std::cout)const;
		void print_inorder(const string& delim = " ", std::ostream& os = std::cout)const;
		void print_postorder(const string& delim = " ", std::ostream& os = std::cout)const;
		void print_levelorder(const string& delim = " ", std::ostream& os = std::cout)const;
	private:
		node *singleLeftLeftRotate(node *k2);
		node *doubleLeftRightRotate(node * k3);
		node *doubleRightLeftRotate(node * k3);
		node *singleRightRightRotate(node * k2);
	private:
		void insert_elem(const T& val, node *&p);
		void erase_elem(const T& val, node *&p);
		void destroyAndDeallocateAllNodes(node *p);
		size_t getHeight(const node *p)const { return p == 0 ? 0 : p->height_; }
		const_iterator find_min_aux(const node *ptr)const;
		const_iterator find_max_aux(const node *ptr)const;
		const_iterator find_aux(const T& val, const node *ptr)const;
		void print_preorder_aux(const string& delim, std::ostream& os, const node *ptr)const;
		void print_inorder_aux(const string& delim, std::ostream& os, const node *ptr)const;
		void print_postorder_aux(const string& delim, std::ostream& os, const node *ptr)const;
	};// end of avl_tree
	namespace Detail {
		//class of avl tree iterator
		template<class T>//T = node
		class avl_iter :
			public iterator<forward_iterator_tag, typename avl_tree<typename T::value_type>::value_type> {
		private:
			template<class T>
			friend class avl_tree;
		private:
			//typedef typename avl_tree<typename T::value_type>::value_type value_type;
			typedef typename avl_tree<typename T::value_type>::const_reference const_reference;
			typedef typename const T::value_type *const_pointer;
			typedef const avl_tree<typename T::value_type> * cntrPtr;
		private:
			const T *ptr_;
			cntrPtr container_;
			stack<const T *> parent_;//保存从root到ptr_的父节点的路径
			std::set<const T *> visited_;//当前节点是否被访问过(此node被访问说明其左子树已被访问了)
		public:
			avl_iter(const T *ptr, cntrPtr container);

			operator const T*()const { return ptr_; }
			const_reference operator*()const { return ptr_->data_; }
			const_pointer operator ->()const { return &(operator*()); }

			avl_iter left()const { return avl_iter(ptr_->left_, container_); }
			avl_iter right()const { return avl_iter(ptr_->right_, container_); }

			avl_iter& operator ++();
			avl_iter operator ++(int);
		public:
			template<class T>
			friend bool operator ==(const avl_iter<T>& it1, const avl_iter<T>& it2);
			template<class T>
			friend bool operator !=(const avl_iter<T>& it1, const avl_iter<T>& it2);
		};//end of avl_iter
	}
}


#include "Detail\AVLTree.impl.h"
#endif

impl.h文件

#pragma once
#ifndef _AVL_TREE_IMPL_H_
#define _AVL_TREE_IMPL_H_
namespace mySTL {
	//detail内的内容与bst一致
	namespace Detail {
		//在获得迭代器的同时还要获得其visited
		template<class T>
		avl_iter<T>::avl_iter(const T *ptr, cntrPtr container)
			:ptr_(ptr), container_(container) {
			if (!ptr_)
				return;
			auto temp = container_->root_;
			while (temp && temp != ptr_ && temp->data_ != ptr_->data_) {
				parent_.push(temp);
				if (temp->data_ < ptr_->data_) {
					//temp向右走说明temo指向的父节点不需要再次访问了
					visited_.insert(temp);//add 2015.01.14
					temp = temp->right_;
				}
				else if (temp->data_ > ptr_->data_) {
					temp = temp->left_;
				}
			}
		}
		template<class T>
		avl_iter<T>& avl_iter<T>::operator ++() {
			visited_.insert(ptr_);//此node被访问
			if (ptr_->right_) {//此node还有右子树
				//rvisited_.insert(ptr_);
				parent_.push(ptr_);
				ptr_ = ptr_->right_;
				while (ptr_ && ptr_->left_) {
					parent_.push(ptr_);
					ptr_ = ptr_->left_;
				}
			}
			else {//node无右子树则只能向父节点路径移动
				ptr_ = 0;//add 2015.01.14
				while (!parent_.empty()) {
					ptr_ = parent_.top();
					parent_.pop();
					if (visited_.count(ptr_) == 0) {//父节点尚未访问,此时ptr_指向此节点
						visited_.insert(ptr_);
						break;
					}
					ptr_ = 0;//设为哨兵
				}//end of while
			}//end of if
			return *this;
		}
		template<class T>
		avl_iter<T> avl_iter<T>::operator ++(int) {
			auto res = *this;
			++*this;
			return res;
		}
		template<class T>
		bool operator ==(const avl_iter<T>& it1, const avl_iter<T>& it2) {
			return it1.ptr_ == it2.ptr_;
		}
		template<class T>
		bool operator !=(const avl_iter<T>& it1, const avl_iter<T>& it2) {
			return !(it1 == it2);
		}
	}
	//析构
	template<class T>
	void avl_tree<T>::destroyAndDeallocateAllNodes(node *p) {
		if (p != 0) {
			destroyAndDeallocateAllNodes(p->left_);
			destroyAndDeallocateAllNodes(p->right_);
			dataAllocator::destroy(p);
			dataAllocator::deallocate(p);
		}
	}
	template<class T>
	avl_tree<T>::~avl_tree() {
		destroyAndDeallocateAllNodes(root_);
	}
	//左旋
	template<class T>
	typename avl_tree<T>::node *avl_tree<T>::singleLeftLeftRotate(node *k2) {
		auto k1 = k2->left_;
		k2->left_ = k1->right_;
		k1->right_ = k2;
		k2->height_ = max(getHeight(k2->left_), getHeight(k2->right_)) + 1;
		k1->height_ = max(getHeight(k1->left_), k2->height_) + 1;
		return k1;
	}
	//先左子树右旋在左旋
	template<class T>
	typename avl_tree<T>::node *avl_tree<T>::doubleLeftRightRotate(node * k3) {
		k3->left_ = singleRightRightRotate(k3->left_);
		return singleLeftLeftRotate(k3);
	}
	//先右子树左旋在有旋
	template<class T>
	typename avl_tree<T>::node *avl_tree<T>::doubleRightLeftRotate(node * k3) {
		k3->right_ = singleLeftLeftRotate(k3->right_);
		return singleRightRightRotate(k3);
	}
	//右旋
	template<class T>
	typename avl_tree<T>::node *avl_tree<T>::singleRightRightRotate(node * k2) {
		auto k1 = k2->right_;
		k2->right_ = k1->left_;
		k1->left_ = k2;
		k2->height_ = max(getHeight(k2->left_), getHeight(k2->right_)) + 1;
		k1->height_ = max(k2->height_, getHeight(k1->right_)) + 1;
		return k1;
	}
	template<class T>
	void avl_tree<T>::erase_elem(const T& val, node *&p) {
		if (p == 0)
			return;
		if (p->data_ != val) {
			if (val < p->data_)
				return erase_elem(val, p->left_);
			else
				return erase_elem(val, p->right_);
		}
		//删除操作与bst一致,只是需要旋转处理
		else { // found
			if (p->left_ != 0 && p->right_ != 0) {// has two children
				size_t choose = size_ % 2;
				//随机选择删除左右,使得删除操作更平衡
				auto pos = (choose == 0 ?
					const_cast<node *>(find_min_aux(p->right_).ptr_) : const_cast<node *>(find_max_aux(p->left_).ptr_));
				p->data_ = pos->data_;
				return (choose == 0 ? erase_elem(pos->data_, p->right_) : erase_elem(pos->data_, p->left_));
			}
			else { //has one or no child
				auto temp = p;
				if (p->left_ == 0)
					p = p->right_;
				else
					p = p->left_;
				dataAllocator::destroy(temp);
				dataAllocator::deallocate(temp);
				--size_;
			}
		}
		//旋转处理
		if (p != 0) {//最后更新p的节点高度信息和旋转维持平衡
			//本段无法理解就画图吧()
			p->height_ = max(getHeight(p->left_), getHeight(p->right_)) + 1;
			if (getHeight(p->left_) - getHeight(p->right_) == 2) {
				if (p->left_->right_ == 0)
					singleLeftLeftRotate(p);
				else
					doubleLeftRightRotate(p);
			}
			else if (getHeight(p->right_) - getHeight(p->left_) == 2) {
				if (p->right_->left_ == 0)
					singleRightRightRotate(p);
				else
					doubleRightLeftRotate(p);
			}
		}
	}
	template<class T>
	void avl_tree<T>::erase(const T& val) {
		return erase_elem(val, root_);
	}
	//插入函数
	template<class T>
	void avl_tree<T>::insert_elem(const T& val, node *&p) {
		if (p == 0) {//根节点为空
			p = dataAllocator::allocate();
			dataAllocator::construct(p);
			p->data_ = val;
			p->left_ = p->right_ = 0;
			p->height_ = 1;
			++size_;
		}
		else if (p->data_ < val) {
			insert_elem(val, p->right_);
			if (getHeight(p->right_) - getHeight(p->left_) == 2) {
				if (val > p->right_->data_)//加入了右子树,单右旋
					p = singleRightRightRotate(p);
				else//否则双旋
					p = doubleRightLeftRotate(p);
			}
		}
		else if (p->data_ > val) {
			insert_elem(val, p->left_);
			if (getHeight(p->left_) - getHeight(p->right_) == 2) {
				if (val < p->left_->data_)
					p = singleLeftLeftRotate(p);
				else
					p = doubleLeftRightRotate(p);
			}
		}
		p->height_ = max(getHeight(p->left_), getHeight(p->right_)) + 1;
	}
	template<class T>
	void avl_tree<T>::insert(const T& val) {
		return insert_elem(val, root_);
	}
	template<class T>
	template<class Iterator>
	void avl_tree<T>::insert(Iterator first, Iterator last) {
		for (; first != last; ++first)
			insert(*first);
	}
	//各种遍历(同bst)
	template<class T>
	void avl_tree<T>::print_preorder_aux(const string& delim, std::ostream& os, const node *ptr)const {
		if (ptr != 0) {
			os << ptr->data_ << delim;
			print_preorder_aux(delim, os, ptr->left_);
			print_preorder_aux(delim, os, ptr->right_);
		}
	}
	template<class T>
	void avl_tree<T>::print_preorder(const string& delim, std::ostream& os)const {
		print_preorder_aux(delim, os, root_);
	}
	template<class T>
	void avl_tree<T>::print_inorder_aux(const string& delim, std::ostream& os, const node *ptr)const {
		if (ptr != 0) {
			print_inorder_aux(delim, os, ptr->left_);
			os << ptr->data_ << delim;
			print_inorder_aux(delim, os, ptr->right_);
		}
	}
	template<class T>
	void avl_tree<T>::print_inorder(const string& delim, std::ostream& os)const {
		print_inorder_aux(delim, os, root_);
	}
	template<class T>
	void avl_tree<T>::print_postorder_aux(const string& delim, std::ostream& os, const node *ptr)const {
		if (ptr != 0) {
			print_postorder_aux(delim, os, ptr->left_);
			print_postorder_aux(delim, os, ptr->right_);
			os << ptr->data_ << delim;
		}
	}
	template<class T>
	void avl_tree<T>::print_postorder(const string& delim, std::ostream& os)const {
		print_postorder_aux(delim, os, root_);
	}
	template<class T>
	void avl_tree<T>::print_levelorder(const string& delim, std::ostream& os)const {
		auto temp = root_;
		if (temp != 0) {
			std::deque<node *> q;
			q.push_back(temp);
			while (!q.empty()) {
				temp = q.front();
				q.pop_front();
				os << temp->data_ << delim;
				if (temp->left_ != 0) q.push_back(temp->left_);
				if (temp->right_ != 0) q.push_back(temp->right_);
			}
		}
	}
	//各种查找(同bst)
	template<class T>
	typename avl_tree<T>::const_iterator avl_tree<T>::find_aux(const T& val, const node *ptr)const {
		while (ptr != 0) {
			if (ptr->data_ < val)
				ptr = ptr->right_;
			else if (ptr->data_ > val)
				ptr = ptr->left_;
			else
				break;
		}
		return const_iterator(ptr, this);
	}
	template<class T>
	typename avl_tree<T>::const_iterator avl_tree<T>::find(const T& val)const {
		return find_aux(val, root_);
	}
	template<class T>
	typename avl_tree<T>::const_iterator avl_tree<T>::find_max_aux(const node *ptr)const {
		while (ptr != 0 && ptr->right_ != 0)
			ptr = ptr->right_;
		return const_iterator(ptr, this);
	}
	template<class T>
	typename avl_tree<T>::const_iterator avl_tree<T>::find_max()const {
		return find_max_aux(root_);
	}
	template<class T>
	typename avl_tree<T>::const_iterator avl_tree<T>::find_min_aux(const node *ptr)const {
		while (ptr != 0 && ptr->left_ != 0)
			ptr = ptr->left_;
		return const_iterator(ptr, this);
	}
	template<class T>
	typename avl_tree<T>::const_iterator avl_tree<T>::find_min()const {
		return find_min_aux(root_);
	}
}
#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值