C++线索二叉树-插入和删除用非递归算法

本文介绍了一种名为ThreadTree的模板类,用于构建线索二叉树,支持查找最大/最小元素、判断空树、插入/删除操作。它通过ThreadNode结构和一系列辅助方法如find_pre、find_next实现高效的数据结构管理。
摘要由CSDN通过智能技术生成
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* p = t, * newroot = new ThreadNode
		(t->element, nullptr, nullptr, 1, 1), * q = newroot;
		stack<ThreadNode*> st1, st2;
		while (p != nullptr || !st1.empty())
		{
			if (p != nullptr)
			{
				st1.push(p);
				st2.push(q);
				if (p->ltag != 1)
				{
					q->ltag = 0;
					q->left = new ThreadNode
					(p->left->element, nullptr, nullptr, 1, 1);
					p = p->left;
					q = q->left;
				}
				else
				{
					p = nullptr;
					q = nullptr;
				}

			}
			else
			{
				p = st1.top();
				st1.pop();
				q = st2.top();
				st2.pop();
				if (pre->rtag == 1)
				{
					pre->right = q;
				}
				if (q->ltag == 1)
				{
					q->left = pre;
				}
				pre = q;
				if (p->rtag != 1)
				{
					q->rtag = 0;
					q->right = new ThreadNode(p->right->element, nullptr, nullptr, 1, 1);
					p = p->right;
					q = q->right;
				}
				else
				{
					p = q = nullptr;
				}

			}
		}
		return newroot;
	}
	ThreadNode* findMax(ThreadNode* t) const
	{
		if (t == nullptr)
		{
			return t;
		}
		while (t->rtag != 1)
		{
			t = t->right;
		}
		return t;
	}
	ThreadNode* findMin(ThreadNode* t) const
	{
		if (t == nullptr)
		{
			return t;
		}
		while (t->ltag != 1)
		{
			t = t->left;
		}
		return t;
	}
	bool contains(const Comparable& x, ThreadNode* t) const
	{
		if (t == nullptr)
		{
			return false;
		}
		while (x < t->element && t->ltag != 1 || x > t->element && t->rtag != 1)
		{
			if (x < t->element && t->ltag != 1)
			{
				t = t->left;
			}
			else
			{
				t = t->right;
			}
		}
		return x == t->element;
	}
	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;
		}
		ThreadNode* p = t;
		while (x < p->element && p->ltag != 1 || x > p->element && p->rtag != 1)
		{
			if (x < p->element && p->ltag != 1)
			{
				large = p;
				p = p->left;
			}
			else
			{
				small = p;
				p = p->right;
			}
		}
		if (x != p->element)
		{
			ThreadNode* add;
			if (x < p->element)
			{
				large = p;
				p->left = add = new ThreadNode(x, small, large, 1, 1);
				p->ltag = 0;
				if (small->rtag == 1)
				{
					small->right = add;
				}
			}
			else if (x > p->element)
			{
				small = p;
				p->right = add = new ThreadNode(x, small, large, 1, 1);
				p->rtag = 0;
				if (large->ltag == 1)
				{
					large->left = add;
				}
			}
		}
	}
	void erase(const Comparable& x, ThreadNode*& t)
	{
		if (t == nullptr)//空树
		{
			return;
		}
		ThreadNode* pre = nullptr, * p = t;
		while (x < p->element && p->ltag != 1 || x > p->element && p->rtag != 1)
		{
			pre = p;
			if (x < p->element && p->ltag != 1)
			{

				p = p->left;
			}
			else
			{
				p = p->right;
			}
		}
		if (x == p->element)
		{
			if (p->rtag != 1 && p->ltag != 1)
			{
				p->element = findMin(p->right)->element;
				erase(p->element, p->right);
			}
			else
			{
				ThreadNode* p_pre = find_pre(p), * p_next = find_next(p);
				ThreadNode* p_child = nullptr;
				if (p->ltag != 1)
				{
					p_child = p->left;
				}
				else if (p->rtag != 1)
				{
					p_child = p->right;
				}
				//pre指针为空
				if (pre == nullptr)
				{
					t = p_child;
				}
				//删除结点为叶子结点,需要更新其双亲的ltag或rtag项
				if (p_child == nullptr)
				{
					if (p_next->left == p)
					{
						p_next->ltag = 1;
					}
					else if (p_pre->right == p)
					{
						p_pre->rtag = 1;
					}
					
				}
				else if (pre != nullptr) // 删除结点不为叶子结点,只需要更新其双亲结点的左右孩子指针。
				{
					if (pre->right == p)
					{
						pre->right = p_child;
					}
					else
					{
						pre->left = p_child;
					}
				}

				//更新前驱后继结点对应指针
				if (p_pre->rtag == 1)
				{
					p_pre->right = p_next;
				}
				if (p_next->ltag == 1)
				{
					p_next->left = p_pre;
				}
				delete p;
			}
			
		}
	}

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值