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;
}
}
}
};
C++线索二叉树-插入和删除用非递归算法
最新推荐文章于 2023-11-23 19:31:19 发布
本文介绍了一种名为ThreadTree的模板类,用于构建线索二叉树,支持查找最大/最小元素、判断空树、插入/删除操作。它通过ThreadNode结构和一系列辅助方法如find_pre、find_next实现高效的数据结构管理。
摘要由CSDN通过智能技术生成