二叉樹搜尋樹的懶惰刪除及相關的其他例程
阿新 • • 發佈:2019-02-03
對於一棵二叉樹,如果刪除的次數不多,通常可以使用懶惰刪除策略:當一個元素要被刪除時,它仍留在樹中,只是做一個刪除的記號。但因為這個記號的存在,所以要修改插入等其他操作。
程式碼的最後給出了刪除葉子節點和輸出指定範圍內的節點的定義,僅供參考。
#include<iostream>
#include<cstdlib>
using namespace std;
template<typename T>
class BinaryTree{
public:
T element;
BinaryTree* left;
BinaryTree* right;
bool deleted; //懶惰刪除識別符號
BinaryTree(T e, BinaryTree* l = NULL, BinaryTree* r = NULL) :element(e), left(l), right(r){ deleted = false; }
void printNode(){
cout << this->element << " ";
}
};
template<typename T>
class binarySearchTree{
private:
BinaryTree<T> * root;
public:
binarySearchTree(){
root = NULL;
}
void insert(const T & x){
insert(x, root);
}
void printTree(){
cout << "中序" << endl;
printTree(root);
cout << endl << "後序" << endl;
printTree(root, 1);
}
//懶惰刪除
void lazyDelete(const T & x){
lazyDelete(x, root);
}
T findMax(){
return findMax(root)->element;
}
T findMin(){
return findMin(root)->element;
}
//刪除所有葉子節點
void removeLeaves(){
removeLeaves(root);
}
//輸出一定範圍內的節點
void printRange(const T & x,const T& y)const{
printRange(root, x, y);
}
private:
//懶惰刪除情況下的插入節點
void insert(const T & x, BinaryTree<T>*&t){
if (t == NULL){
t = new BinaryTree<T>(x);
}
//如果是懶惰刪除的節點,則直接替換值
else if (t->deleted == true){
t->element = x;
t->deleted = false ;
}
else if (x < t->element){
insert(x, t->left);
}
else if (t->element < x){
insert(x, t->right);
}
else{
;
}
}
//懶惰刪除情況下的最大值
BinaryTree<T>* findMax( BinaryTree<T>* t)const{
if (t == NULL){
return NULL;
}
//如果是懶惰刪除的點則跳過
if (t->right == NULL || t->right->deleted==true){
return t;
}
return findMax(t->right);
}
//懶惰刪除情況下的最小值
BinaryTree<T>* findMin(BinaryTree<T>* t)const{
if (t == NULL){
return NULL;
}
//如果是懶惰刪除的點則跳過
else if (t->left == NULL || t->left->deleted == true){
return t;
}
else{
return findMin(t->left);
}
}
//懶惰刪除情況下的中序遍歷列印樹
void printTree(BinaryTree<T>*t)const{
if (t != NULL){
printTree(t->left);
if (t->deleted == true){
cout << ' ';
}
else{
cout << t->element << ' ';
}
printTree(t->right);
}
}
//懶惰刪除情況下的後序遍歷列印樹
void printTree(BinaryTree<T>*t, int x)const{
if (t != NULL){
printTree(t->left,1);
printTree(t->right,1);
if (t->deleted == true){
cout << ' ';
}
else{
cout << t->element << ' ';
}
}
}
//懶惰刪除節點
void lazyDelete(const T & x, BinaryTree<T>* &t){
if (t == NULL){
return;
}
else if (x < t->element){
lazyDelete(x, t->left);
}
else if (x>t->element){
lazyDelete(x, t->right);
}
else{
//只做識別符號的變換,不直接刪除
if (t->deleted == true){
return;
}
else{
t->deleted = true;
return;
}
}
}
//刪除樹葉節點
void removeLeaves(BinaryTree<T>* &t){
if (t == NULL || (t->left == NULL && t->right == NULL)){
delete t;
t = NULL;
}
else{
removeLeaves(t->left);
removeLeaves(t->right);
}
}
//輸出一定範圍內的節點
void printRange(BinaryTree<T>*t, const T & x, const T& y)const{
if (t == NULL){
return;
}
if (t->element >= x){
printRange(t->left, x, y);
}
if (x <= t->element && t->element <= y){
t->printNode();
}
if (t->element <= y){
printRange(t->right, x, y);
}
}
};