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;
}
}
}
}
};
C++线索二叉树类模板,添加和删除用递归算法
最新推荐文章于 2022-07-20 18:05:41 发布