C++线索二叉树类模板,添加和删除用递归算法

template <typename Comparable>
class ThreadTree
{
private:
	struct ThreadNode //线索二叉树结点定义
	{
		Comparable element;
		ThreadNode* left, * right;
		int ltag, rtag; //0表示指向左右孩子,1表示指向前驱后继结点
		explicit ThreadNode(const Comparable& el = Comparable{}, ThreadNode* le = nullptr,
			ThreadNode* ri = nullptr, int lt = 0, int rt = 0) :element(el), left(le), right(ri),
			ltag(lt), rtag(rt) {};
	};
	ThreadNode* root, * head, * tail;
	void init() //线索二叉树初始化
	{
		root = nullptr;
		head = new ThreadNode(Comparable{}, nullptr, nullptr, 1, 1);
		tail = new ThreadNode(Comparable{}, nullptr, nullptr, 1, 1);
		head->right = tail;
		tail->left = head;
	}
public:

	ThreadTree()
	{
		init();
	}
	ThreadTree(const ThreadTree& rhs)
	{
		init();
		clone(rhs.root);

	}
	ThreadTree(ThreadTree&& rhs) :root(rhs.root), head(rhs.head), tail(rhs.tail)
	{
		rhs.root = nullptr;
		rhs.head = nullptr;
		rhs.tail = nullptr;
	}
	ThreadTree& operator = (const ThreadTree& rhs)
	{
		ThreadTree copy = rhs;
		std::swap(*this, copy);
		return *this;
	}
	ThreadTree& operator = (ThreadTree&& rhs)
	{
		std::swap(root, rhs.root);
		std::swap(head, rhs.head);
		std::swap(tail, rhs.tail);
		return *this;
	}
	~ThreadTree()
	{
		makeEmpty();
		delete head;
		delete tail;
	}

	const Comparable& findMax() const //找到树中最大元素
	{
		return findMax(root)->element;
	}
	const Comparable& findMin() const
	{
		return findMin(root)->element;
	}
	bool contains(const Comparable& x) const
	{
		return contains(x, root);
	}
	bool isEmpty() const//判断树是否为空
	{
		return root == nullptr;
	}
	void printTree(ostream& out = cout) const
	{
		printTree(head, out);
	}
	void makeEmpty()
	{
		makeEmpty(head);
	}
	void clone(ThreadNode* t) //复制树
	{
		ThreadNode* pre = head;
		root = clone(t, pre);
		pre->rtag = 1;
		pre->right = tail;
		tail->left = pre;
	}
	//插入删除公有方法,调用私有方法
	void insert(const Comparable& x)
	{
		insert(x, root, head, tail);
	}
	void erase(const Comparable& x)
	{
		erase(x, root);
	}

private:
	ThreadNode* find_pre(ThreadNode* t) const //找结点的前驱结点
	{
		if (t == nullptr)
		{
			return nullptr;
		}
		else if (t->ltag == 1)
		{
			return t->left;
		}
		else if (t->ltag == 0)
		{
			ThreadNode* p = t->left;
			while (p->rtag != 1)
			{
				p = p->right;
			}
			return p;
		}
	}
	ThreadNode* find_next(ThreadNode* t) const//找结点的后继结点
	{
		if (t == nullptr)
		{
			return nullptr;
		}
		else if (t->rtag == 1)
		{
			return t->right;
		}
		else if (t->rtag == 0)
		{
			ThreadNode* p = t->right;
			while (p->ltag != 1)
			{
				p = p->left;
			}
			return p;
		}
	}
	ThreadNode* clone(ThreadNode* t, ThreadNode* & pre)//复制树,中序遍历复制
	{
		if (t == nullptr)
		{
			return nullptr;
		}
		ThreadNode* newroot = new ThreadNode(t->element, nullptr, nullptr, 1, 1);
		if (t->ltag != 1)
		{
			newroot->ltag = 0;//结点有左孩子,后续不需要添加前驱指针
			newroot->left = clone(t->left, pre);
		}
		if (pre == head)
		{
			pre->right = newroot;
		}
		else if (pre->rtag == 1)//前一个结点的右孩子为空,需要添加后继指针
		{
			pre->right = newroot;

		}
		if (newroot->ltag == 1)//当前节点的左孩子为空,需要添加前驱指针
		{
			newroot->left = pre;
		}
		pre = newroot;
		if (t->rtag != 1)
		{
			newroot->rtag = 0;//结点有右孩子,后续不需要添加后继指针
			newroot->right = clone(t->right, pre);
		}

		return newroot;
	}
	ThreadNode* findMax(ThreadNode* t) const
	{
		if (t == nullptr || t->rtag == 1)
		{
			return t;
		}
		return findMax(t->right);
	}
	ThreadNode* findMin(ThreadNode* t) const
	{
		if (t == nullptr || t->ltag == 1)
		{
			return t;
		}
		return findMin(t->left);
	}
	bool contains(const Comparable& x, ThreadNode* t) const
	{
		if (t == nullptr)
		{
			return false;
		}
		else if (t->ltag != 1 && x < t->element)
		{
			return contains(x, t->left);
		}
		else if (t->rtag != 1 && x > t->element)
		{
			return contains(x, t->right);
		}
		else if (t->element == x)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	void printTree(ThreadNode* hd, ostream& out) const
	{
		ThreadNode* p = find_next(hd);
		int i = 0;
		while (p != tail)
		{
			out << "#" << ++i << ": " << p->element << endl;
			p = find_next(p);
		}
	}
	void makeEmpty(ThreadNode* head)
	{
		ThreadNode* p = find_next(head), * temp;
		while (p != tail)
		{
			temp = p;
			p = find_next(p);
			delete temp;
		}

	}
	void insert(const Comparable& x, ThreadNode*& t, ThreadNode* small, ThreadNode* large)
	{
		if (t == nullptr) //树为空
		{
			t = new ThreadNode(x, small, large, 1, 1);
			small->right = t;
			large->left = t;
			return;
		}
		else if (t->ltag == 0 && x < t->element) //左子树不为空,且插入元素小于左子树根结点的值
		{
			insert(x, t->left, small, t);
		}
		else if (t->rtag == 0 && x > t->element)//右子树不为空,且插入元素大于右子树根结点的值
		{
			insert(x, t->right, t, large);
		}
		else if (t->ltag == 1 && x < t->element)//左子树为空,且插入元素小于左子树根结点的值
		{
			ThreadNode* p = new ThreadNode(x, small, t, 1, 1);
			//更新左子树根结点的ltag和左孩子指针
			t->left = p;
			t->ltag = 0;
			//更新插入结点前驱结点的后继指针
			if (small->rtag == 1)
			{
				small->right = p;
			}
		}
		else if (t->rtag == 1 && x > t->element)//右子树为空,且插入元素大于右子树根结点的值
		{
			ThreadNode* p = new ThreadNode(x, t, large, 1, 1);

			t->right = p;
			t->rtag = 0;

			if (large->ltag == 1)
			{
				large->left = p;
			}
		}
	}
	void erase(const Comparable& x, ThreadNode*& t)
	{
		if (t == nullptr)//空树
		{
			return;
		}
		else if (t->ltag == 0 && x < t->element) // t结点的左子树不为空,且x小于t结点的值
		{
			erase(x, t->left);
		}
		else if (t->rtag == 0 && x > t->element)
		{
			erase(x, t->right);
		}
		else if (x == t->element)
		{
			if (t->ltag == 0 && t->rtag == 0) //结点所在左右子树不为空,转化为删除其后继结点。
			{
				t->element = findMin(t->right)->element;
				erase(t->element, t->right);
			}
			else //结点至少有一颗子树为空
			{
				ThreadNode* old = t, * t_pre = find_pre(t), * t_next = find_next(t);
				if (t->ltag == 1 && t->rtag == 1) //为叶子结点,更新双亲的ltag或rtag
				{
					if (t_next->left == t)
					{
						t_next->ltag = 1;
					}
					if (t_pre->right == t)
					{
						t_pre->rtag = 1;
					}
				}
				//删除结点有左子树或右子树不为空,无需更新双亲结点的ltag和rtag,只需要更新双亲的孩子结点指针。
				else if (t->ltag != 1)
				{
					t = t->left;
				}
				else if (t->rtag != 1) 
				{
					t = t->right;
				}


				//更新删除结点的前驱和后继对应指针值
				if (t_pre->rtag == 1)
				{
					t_pre->right = t_next;
				}
				if (t_next->ltag == 1)
				{
					t_next->left = t_pre;
				}

			}
		}
	}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值