线索树利用中序遍历来维护
其中树中删除操作分别讨论
1)无儿子
2)有一个儿子–>分四种情况讨论
3)有两个儿子–>与将左子树最右的结点互换值,转化为问题(1)和(2)
/*
二叉搜索树+二叉线索树的合并
搜索树插入与删除同时维护了前序和后序
样例
8
8 6 7 5 10 9 12 11
*/
#include<iostream>
using namespace std;
template<class Item>
class binary_tree_node {
public:
//TYPEDEF
typedef Item value_type;
//CONSTRUCTOR
binary_tree_node(
const Item &init_data = Item(),
binary_tree_node *init_left = NULL,
binary_tree_node *init_right = NULL,
binary_tree_node *init_parent = NULL,
bool init_left_flag = 0,
bool init_right_flag = 0
) {
data_field = init_data;
left_field = init_left;
right_field = init_right;
left_flag = init_left_flag;
right_flag = init_right_flag;
parent_field = init_parent;
}
//MODIFICATION MEMBER FUNCTIONS
Item &data() { return data_field; }
bool &LeftFlag() { return left_flag; }
bool &RightFlag() { return right_flag; }
binary_tree_node *left() { return left_field; }
binary_tree_node *right() { return right_field; }
binary_tree_node *parent() { return parent_field; }
void set_data(const Item &new_data) { data_field = new_data; }
void set_left_flag(const bool &new_flag) { left_flag = new_flag; }
void set_right_flag(const bool &new_flag) { right_flag = new_flag; }
void set_left(binary_tree_node *new_left) { left_field = new_left; }
void set_right(binary_tree_node *new_right) { right_field = new_right; }
void set_parent(binary_tree_node *new_parent) { parent_field = new_parent; }
private:
Item data_field;
binary_tree_node *parent_field;
binary_tree_node *left_field;
binary_tree_node *right_field;
bool left_flag;
bool right_flag;
};
template<class Item>
class binary_search_tree {
public:
binary_search_tree(binary_tree_node<Item> *init_head = NULL) {
head = init_head;
}
void insert_node(Item data);//二叉树插入结点,并维护已有的中序线索
binary_tree_node<Item> *find(Item data);//二叉树查询一个元素,并返回指向该元素的指针
void erase(Item data);//清除一个元素
binary_tree_node<Item> *in_findpre(binary_tree_node<Item> *ptr);//查找该指针指向元素的前序
binary_tree_node<Item> *in_findnext(binary_tree_node<Item> *ptr);//查找该指针指向元素的后序
void In_Traverse();//进行中序遍历
void tree_clear(binary_tree_node<Item> *root = NULL);//清除树
private:
binary_tree_node<Item> *head;
};
/*二叉树插入结点,并维护已有的中序线索*/
template<class Item>
void binary_search_tree<Item>::insert_node(Item data) {
if (head == NULL) {
head = new binary_tree_node<Item>(data);
return;
}
binary_tree_node<Item> *root = head;
while (1) {
while (data > root->data() && root->RightFlag() == 0 && root->right() != NULL)
root = root->right();
if (data > root->data()) {
binary_tree_node<Item> *node = new binary_tree_node<Item>(data);
node->set_right(root->right());
node->RightFlag() = root->RightFlag();
node->set_left(root);
node->LeftFlag() = 1;
root->set_right(node);
node->set_parent(root);
root->RightFlag() = 0;
break;
}
while (data <= root->data() && root->LeftFlag() == 0 && root->left() != NULL)
root = root->left();
if (data <= root->data()) {
binary_tree_node<Item> *node = new binary_tree_node<Item>(data);
node->set_left(root->left());
node->LeftFlag() = root->LeftFlag();
node->set_right(root);
node->RightFlag() = 1;
root->set_left(node);
node->set_parent(root);
root->LeftFlag() = 0;
break;
}
}
return;
}
/*二叉树查找某一个结点并返回指向它的指针*/
template<class Item>
binary_tree_node<Item> *binary_search_tree<Item>::find(Item data) {
binary_tree_node<Item> *root = head;
while (1) {
while (data > root->data() && root->RightFlag() == 0 && root->right() != NULL)
root = root->right();
if (data > root->data()) {
cout << "This node is not in the tree" << endl;
break;
}
while (data < root->data() && root->LeftFlag() == 0 && root->left() != NULL)
root = root->left();
if (data < root->data()) {
cout << "This node is not in the tree" << endl;
break;
}
if (data == root->data()) break;
}
if (data == root->data()) return root;
else return NULL;
}
/*二叉树删除某一个结点*/
template<class Item>
void binary_search_tree<Item>::erase(Item data) {
binary_tree_node<Item> *node = find(data);
if (node == NULL) return;
binary_tree_node<Item> *pre = in_findpre(node);
binary_tree_node<Item> *next = in_findnext(node);
binary_tree_node<Item> *father = node->parent();
if (node->LeftFlag() == 0 && node->RightFlag() == 0 && node->left() != NULL && node->right() != NULL) {//有两个儿子结点
node->data() = pre->data();
node = pre;
pre = in_findpre(node);
next = in_findnext(node);
}
if ((node->LeftFlag() == 1 && node->RightFlag() == 1) ||
(node->LeftFlag() == 1 && node->right() == NULL) ||
(node->left() == NULL && node->RightFlag() == 1))//无任何儿子结点
{
if (pre->RightFlag() == 1) {
pre->set_right(next);
} else {
if (pre->right() == node) {
pre->set_right(next);
pre->RightFlag() = 1;
}
}
if (next->LeftFlag() == 1) {
next->set_left(pre);
} else {
if (next->left() == node) {
next->set_left(pre);
next->LeftFlag() = 1;
}
}
if (node->parent() == NULL) head = NULL;
} else {//有一个儿子结点
if (father->right() == node) {
if (node->LeftFlag() == 0 && node->left() != NULL) {
father->set_right(node->left());
if ((node->left())->RightFlag() == 1) {
(node->left())->set_right(next);
}
} else if (node->right() != NULL && node->RightFlag() == 0) {
father->set_right(node->right());
if ((node->right())->LeftFlag() == 1) {
(node->right())->set_left(father);
}
}
} else if (father->left() == node) {
if (node->LeftFlag() == 0 && node->left() != NULL) {
father->set_left(node->left());
if ((node->left())->RightFlag() == 1) {
(node->left())->set_right(father);
}
} else if (node->right() != NULL && node->RightFlag() == 0) {
father->set_left(node->right());
if ((node->right())->LeftFlag() == 1) {
(node->right())->set_left(next);
}
}
}
if (node->parent() == NULL) {
if (node->left() != NULL && node->LeftFlag() == 0) {
head = node->left();
} else if (node->right() != NULL && node->RightFlag() == 0) {
head = node->right();
}
}
}
delete node;
node = NULL;
return;
}
/*中序线索二叉树找前驱*/
template<class Item>
binary_tree_node<Item> *binary_search_tree<Item>::in_findpre(binary_tree_node<Item> *ptr) {
if (ptr->LeftFlag() == 1) return ptr->left();
else {
binary_tree_node<Item> *p = ptr->left();
while (p->RightFlag() == 0 && p->right() != NULL) {
p = p->right();
}
return p;
}
}
/*中序线索二叉树找后继*/
template<class Item>
binary_tree_node<Item> *binary_search_tree<Item>::in_findnext(binary_tree_node<Item> *ptr) {
if (ptr->RightFlag() == 1) return ptr->right();
else {
binary_tree_node<Item> *p = ptr->right();
while (p->LeftFlag() == 0 && p->left() != NULL) {
p = p->left();
}
return p;
}
}
/*二叉树中序遍历*/
template<class Item>
void binary_search_tree<Item>::In_Traverse() {
cout << "inorder_traverse:" << endl;
if (head == NULL) {
cout << "There are no nodes in this tree" << endl;
return;
}
binary_tree_node<Item> *root = head;
while (root->LeftFlag() == 0 && root->left() != NULL) {
root = root->left();
}
cout << root->data() << endl;
while (root->right() != NULL) {
if (root->RightFlag() == 0) {
root = root->right();
while (root->LeftFlag() == 0) {
root = root->left();
}
} else {
root = root->right();
}
cout << root->data() << endl;
}
}
/*清除树*/
template<class Item>
void binary_search_tree<Item>::tree_clear(binary_tree_node<Item> *root) {
if (root == NULL) root = head, head = NULL;
if (root == NULL) return;
if (root != NULL) {
if (root->LeftFlag() == 0 && root->left() != NULL)
tree_clear(root->left());
if (root->RightFlag() == 0 && root->right() != NULL)
tree_clear(root->right());
delete root;
root = NULL;
}
}
int main() {
int n;
cin >> n;
binary_search_tree<int> tre;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
tre.insert_node(x);
}
tre.In_Traverse();//中序输出
cout<<"Delete element 10"<<endl;
tre.erase(10);//删除数字10
tre.In_Traverse(); //再次中序输出
tre.tree_clear();//清除树
return 0;
}