自写STL二叉树容器

最近看完了侯捷的STL源码剖析,自己写个案例练练手
这是一个二叉树的容器,参照stl容器
主要实现以下功能:
1.构造函数:可通过两种方式构造
(1)空构造;(2)设置原生指针或容器的头尾指针/迭代器将其填充,第三个参数为空位符,在树中表示NULL;
2.插入函数:
提供左插入insert_left与右插入insert_right,当对应位置已有节点时将该点作为插入点的子节点,第三个参数设置该子节点为其左子/右子,默认为左子,设0则为右子;
3.擦除函数:
提供节点删除erase与枝删除erasebranch,其中节点删除仅适用于子节点<=1的情况,删除节点后由子节点接替其位置。
枝删除通过后序遍历依次将节点释放。
4.遍历方式:
提供4种遍历模式:①层序遍历levelOrder②前序遍历preorderTraversal③中序遍历inorderTraversal④后序遍历postorderTraversal
第一个参数为遍历的起始节点,第二个为仿函数接口,即遍历过程中要完成的动作。其中层序遍历的仿函数需两个参数,第一个相邻层间过渡的标志,过渡时为1。另一个参数为节点的数值。
5.查找函数find:
第一个参数为需查找的数值,第二个参数为起始节点。返回其迭代器。
6.旋转函数:
提供左旋rotate_left与右旋函数rotate_right,即平衡二叉树中常用的旋转操作。
7.迭代器iterator:
通过迭代器来访问二叉树的节点,可实现节点的移动与访问
(1)移动:++往下,–往上,可通过iter_left,iter_right,选择向下的方向(往左/往右)。
(2)访问:重载与->,可通过访问节点数值,->可访问节点成员变量。

上述功能均通过了简单的测试,但时间有限,还没在实际案例中应用,后续根据需要继续完善功能

代码如下:

//踏梦远行——2020.8.1
#include<iostream>
#include<vector>
#include<queue>
#include<list>
#include<sstream>
using namespace std;

template<class T>
struct treenode
{
	typedef treenode<T>* pointer;
	T data;
	pointer left;
	pointer right;
	pointer parent;
};

//-------------------------

template<class T>
class treeiter
{
public:
	typedef treenode<T>* pointer;
	treeiter() :itertype(0) {};
	treeiter(pointer n) :node(n),itertype(0) {};
	void operator=(pointer n) { node = n; itertype = 0; };
	pointer operator++(int);
	pointer& operator++();
	pointer operator--(int);
	pointer& operator--();
	bool operator==(pointer p)const {return this->node == p;};
	T operator *()const { return node->data; };
	typename treeiter<T>::pointer operator ->() { return node; };
	void iter_left() { itertype = 0; };
	void iter_right() { itertype = 1; };
	pointer node;
private:
	unsigned char itertype;
};

template<class T>
typename treeiter<T>::pointer treeiter<T>::operator++(int)
{
	pointer tmp = node;
	switch (itertype) {
	case 0:node = node->left;
		break;
	case 1:node = node->right;
		break;
	default:
		break;
	}
	return tmp;
}

template<class T>
typename treeiter<T>::pointer& treeiter<T>::operator++()
{
	switch (itertype) {
	case 0:node = node->left;
		break;
	case 1:node = node->right;
		break;
	default:
		break;
	}
	return node;
}

template<class T>
typename treeiter<T>::pointer treeiter<T>::operator--(int)
{
	pointer tmp = node;
	node = node->parent;
	return tmp;
}

template<class T>
typename treeiter<T>::pointer& treeiter<T>::operator--()
{
	node = node->parent;
	return node;
}


//-------------------------

template<class T>
class mytree
{
public:
	typedef treenode<T> value;
	typedef treenode<T>* pointer;
	typedef treeiter<T> iterator;
	mytree();
	template<class U>
	mytree(U l, U r, T sign);
	iterator gethead() { return head; }
	iterator begin() { return head->left; }
	iterator end() { return NULL; }
	void insert_left(treeiter<T> parent, T x, bool left = 1);
	void insert_right(treeiter<T> parent, T x, bool left = 1);
	void erase(treeiter<T> parent);
	void erasebranch(treeiter<T> parent);
	template<class func>
	void levelOrder(iterator pos, func& fun);
	template<class func>
	void preorderTraversal(iterator pos,func& fun);
	template<class func>
	void inorderTraversal(iterator pos, func& fun);
	template<class func>
	void postorderTraversal(iterator pos, func& fun);
	iterator find(T pos, iterator start);
	void rotate_left(iterator start);
	void rotate_right(iterator start);
private:
	pointer head;
	pointer node;
	template<class U>
	void constuctree(U l, U r, T sign, random_access_iterator_tag);
	template<class U>
	void constuctree(U l, U r, T sign, input_iterator_tag);
	pointer createnode() { return new value; }
	void erasebranch_base(iterator parent);
};

template<class T>
mytree<T>::mytree() {
	head = new value;
	head->left = NULL;
	head->right = NULL;
	head->parent = NULL;
	node = head;
};

template<class T>
template<class U>
mytree<T>::mytree(U l, U r,T sign) {
	constuctree( l, r,sign,iterator_traits<U>::iterator_category());
};

template<class T>
template<class U>
void mytree<T>::constuctree(U l, U r, T sign,random_access_iterator_tag)
{
	head = new value;
	head->left = NULL;
	head->right = NULL;
	head->parent = NULL;
	node = head;
	if (l <= r)
	{
		U pos = l;
		treeiter<T> it = head;
		int n = r - l - 1;
		insert_left(it, *pos++);
		queue<pointer> myq;
		myq.push(begin());
		while (n > 0)
		{
			it = myq.front();
			myq.pop();
			if (*pos!=sign) {
				insert_left(it, *pos);
				myq.push(it->left);
			}
			pos++;
			if (!--n)break;
			if (*pos!=sign) {
				insert_right(it, *pos);
				myq.push(it->right);
			}
			pos++;
			--n;
		}
	}
}

template<class T>
template<class U>
void mytree<T>::constuctree(U l, U r, T sign,input_iterator_tag)
{
	head = new value;
	head->left = NULL;
	head->right = NULL;
	head->parent = NULL;
	node = head;
	U pos = l;
	treeiter<T> it = head;
	insert_left(it, *pos++);
	queue<pointer> myq;
	myq.push(head->left);
	while (pos !=r)
	{
		it = myq.front();
		myq.pop();
		if (*pos!=sign) {
			insert_left(it, *pos);
			myq.push(it->left);
		}
		pos++;
		if (pos==r)break;
		if (*pos!=sign) {
			insert_right(it, *pos);
			myq.push(it->right);
		}
		pos++;
	}
}

template<class T>
void mytree<T>::insert_left(treeiter<T> parent, T x, bool left)
{
	node = createnode();
	node->parent = parent.node;
	node->data = x;
	if (left)node->left = parent.node->left;
	else node->right = parent.node->left;
	node->right = NULL;
	parent.node->left = node;
}

template<class T>
void mytree<T>::insert_right(treeiter<T> parent, T x, bool left) {
	node = createnode();
	node->parent = parent.node;
	node->data = x;
	if (left)node->left = parent.node->right;
	else node->right = parent.node->right;
	node->right = NULL;
	parent.node->right = node;
}

template<class T>
void mytree<T>::erase(treeiter<T> parent)
{
	if (!parent->left && !parent->right) {
		if (parent == parent->parent->left)parent->parent->left = NULL;
		else parent->parent->right = NULL;
		delete parent.node;
		return;
	}
	if (!parent->left){
		if (parent->parent->left == parent.node) parent->parent->left = parent->right;
		else parent->parent->right = parent->right;
		parent->right->parent = parent->parent;
		delete parent.node;
		return;
	}
	if (!parent->right) {
		if (parent->parent->left == parent.node) parent->parent->left = parent->left;
		else parent->parent->right = parent->left;
		parent->left->parent = parent->parent;
		delete parent.node;
		return;
	}
}

template<class T>
void mytree<T>::erasebranch(iterator parent)
{
	if (parent == parent->parent->left)parent->parent->left = NULL;
	else parent->parent->right = NULL;
	erasebranch_base(parent);
}

template<class T>
void mytree<T>::erasebranch_base(iterator parent)
{
	if (!parent.node) return;
	erasebranch_base(parent->left);   //后序遍历
	erasebranch_base(parent->right);
	delete parent.node;
}



template<class T>
template<class func>
void mytree<T>::levelOrder(mytree<T>::iterator pos,func& fun) {
	if (!pos.node)return;
	pointer temp;
	queue<pointer> myq;
	myq.push(pos.node);
	int len;
	while (!myq.empty())
	{
		len = myq.size();
		for (int i = 0; i < len; i++)
		{
			temp = myq.front();
			myq.pop();
			fun(!i,temp->data);
			if (temp->left)myq.push(temp->left);
			if (temp->right)myq.push(temp->right);
		}
	}
}

template<class T>
template<class func>
void mytree<T>::preorderTraversal(mytree<T>::iterator pos,func& fun) {
	if (!pos.node) return;
	fun(pos->data);
	preorderTraversal(pos->left,fun);
	preorderTraversal(pos->right,fun);
}

template<class T>
template<class func>
void mytree<T>::inorderTraversal(mytree<T>::iterator pos, func& fun) {
	if (!pos.node) return;
	inorderTraversal(pos->left,fun);
	fun(pos->data);
	inorderTraversal(pos->right,fun);
}

template<class T>
template<class func>
void mytree<T>::postorderTraversal(mytree<T>::iterator pos, func& fun) {
	if (!pos.node) return;
	postorderTraversal(pos->left, fun);
	postorderTraversal(pos->right, fun);
	fun(pos->data);
}

template<class T>
typename mytree<T>::iterator mytree<T>::find(T pos, mytree<T>::iterator start)
{
	if (!start.node)return NULL;
	if (start->data == pos)return start;
	if (find(pos, start->left).node)return find(pos, iterator(start->left));
	if (find(pos, start->right).node)return find(pos, iterator(start->right));
	return NULL;
}

template<class T>
void mytree<T>::rotate_left(mytree<T>::iterator start)
{
	if (!start->right)return;
	if (start == start->parent->right)start->parent->right = start->right;
	else  start->parent->left = start->right;
	start->right->parent = start->parent;
	start->parent = start->right;
	start->right = start->parent->left;
	start->parent->left = start.node;
	if(start->right)start->right->parent = start.node;
	start = start->parent;
}

template<class T>
void mytree<T>::rotate_right(mytree<T>::iterator start)
{
	if (!start->left)return;
	if (start == start->parent->right)start->parent->right = start->left;
	else  start->parent->left = start->left;
	start->left->parent = start->parent;
	start->parent = start->left;
	start->left = start->parent->right;
	start->parent->right = start.node;
	if (start->left)start->left->parent = start.node;
	start = start->parent;
}


//-------------------------

template<class T>
void show(vector<vector<T>> v)
{
	for (int i = 0; i < v.size(); i++)
	{
		for (int j = 0; j < v[i].size()-1; j++)
			cout << v[i][j]<<"| |";
		cout << v[i][v[i].size()-1]<<endl;
	}
}

template<class T>
void show(vector<T> v)
{
	for (int i = 0; i < v.size()-1; i++)
	{
		cout << v[i] << "| |";
	}
	cout << v[v.size() - 1] << endl;
}

class savevec
{
public:
	vector<double> v;
	void operator()(double x)
	{
		v.push_back(x);
	}
	~savevec() { v.clear(); };
};

class savevvec
{
public:
	vector<vector<double>> v;
	void operator()(int sign,double x)
	{
		if (sign)(v.push_back({}));
		v.back().push_back(x);
	}
	~savevvec() { v.clear(); };
};


int main()
{
	double arr[] = { 1,5,6,8,9,7,3,0,9,10 };
	list<double> l(arr, arr + 10);
	mytree<double> t(l.begin(),l.end(),0);
	//treeiter<double> it = t.gethead();
	//t.insert_left(it, 5);
	//it.iter_left();
	//it++;
	//t.insert_left(it, 4.7);
	//t.insert_right(it, 10.5);
	//t.insert_right(it, 9);
	//it--;
	//t.insert_left(it, 8);
	mytree<double>::iterator it = t.begin();
	savevvec savv;
	t.levelOrder(it,savv);
	show(savv.v);
	cout << "----------" << endl;
	savevec sav;
	t.preorderTraversal(it,sav);
	show(sav.v);
	sav.v.clear();
	t.erase(t.find(8, t.begin()));
	t.inorderTraversal(it,sav);
	show(sav.v);
	sav.v.clear();
	t.erasebranch(t.find(6, t.begin()));
	t.postorderTraversal(it,sav);
	show(sav.v);
	sav.v.clear();
	it=t.find(5, t.begin());
	t.rotate_right(it);
	system("pause");
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值