二叉排序樹的結點刪除
阿新 • • 發佈:2019-01-08
8
3 9
2 6 10
1 4 7
5
上面是1到10的二叉排序樹。
如何實現二叉排序樹的節點刪除呢?假設我們刪除結點6,先尋找前驅結點或者後繼節點,6的前驅結點是5,後繼是7,想象一下刪除了結點6後,樹該怎麼變化?其實只要將6改成5,再將5的節點刪除就OK了。
注意前驅或後繼的度為1或者0。
(PS:這是從計蒜客學來的,不是打廣告,侵權則刪)
#include <iostream>
#include <cstdlib>
using namespace std;
class Node
{
public :
int data;
Node *lchild, *rchild, *father;
Node(int _data, Node*_father=NULL){
data = _data;
lchild = NULL;
rchild = NULL;
father = _father;
}
~Node(){
if(lchild != NULL)
delete lchild;
if(rchild != NULL)
delete rchild;
}
void myInsert(int value){
if(data == value)
return;
else if(value < data){
if(lchild == NULL)
lchild = new Node(value, this);
else
lchild->myInsert(value);
}
else{
if(rchild == NULL)
rchild = new Node(value, this);
else
rchild->myInsert(value);
}
}
Node *mySearch(int value){
if(data == value)
return this;
else if(value < data){
if(lchild == NULL)
return NULL;
else
lchild->mySearch(value);
}
else{
if(rchild == NULL)
return NULL;
else
rchild->mySearch(value);
}
}
/*尋找前驅*/
Node *predecessor(){
Node *temp = lchild;
while(temp!=NULL && temp->rchild!=NULL){
temp = temp->rchild;
}
return temp;
}
/*尋找後繼*/
Node *successor(){
Node *temp = rchild;
while(temp!=NULL && temp->lchild!=NULL){
temp = temp->lchild;
}
return temp;
}
/*刪除度為1或0的結點*/
void removeNode(Node *nodeOfdelete){
/*注意一定要將temp初始化為NULL*/
Node *temp = NULL;
if(nodeOfdelete->lchild != NULL){
temp = nodeOfdelete->lchild;
/*更新當前結點的子結點的父節點*/
temp->father = nodeOfdelete->father;
/*注意一定要將要刪除節點的lchild和rchild置為NULL,注意Node類的解構函式*/
nodeOfdelete->lchild = NULL;
}
if(nodeOfdelete->rchild != NULL){
temp = nodeOfdelete->rchild;
temp->father = nodeOfdelete->father;
nodeOfdelete->rchild = NULL;
}
/*上面兩個if只有一個成立,下面if對應的也只有一個成立*/
if(nodeOfdelete->father->lchild == nodeOfdelete)
nodeOfdelete->father->lchild = temp;
if(nodeOfdelete->father->rchild == nodeOfdelete)
nodeOfdelete->father->rchild = temp;
delete nodeOfdelete;
}
bool deleteNode(int value){
Node *currentNode, *nodeOfdelete;
currentNode = mySearch(value);
if(currentNode == NULL)
return false;
/*尋找前驅*/
if(currentNode->lchild != NULL)
nodeOfdelete = currentNode->predecessor();
/*或尋找後繼*/
else if(currentNode->rchild != NULL)
nodeOfdelete = currentNode->successor();
/*要刪除的結點是葉子結點*/
else
nodeOfdelete = currentNode;
/*更改結點的data值*/
currentNode->data = nodeOfdelete->data;
/*因為前驅和後繼都是度為1的結點,如果不是前驅和後繼那一定是葉子結點了,所以可以用remove函式進行刪除*/
removeNode(nodeOfdelete);
return true;
}
void inOrder(){
if(lchild != NULL)
lchild->inOrder();
cout<<data<<" ";
if(rchild != NULL)
rchild->inOrder();
}
};
class BinaryTree
{
private:
Node *root;
public:
BinaryTree(){
root = NULL;
}
~BinaryTree(){
if(root != NULL)
delete root;
}
void myInsert(int value){
if(root == NULL)
root = new Node(value);
else
root->myInsert(value);
}
void mySearch(int value){
if(root->mySearch(value) != NULL)
cout << "存在" <<endl;
else
cout << "不存在" << endl;
}
void deleteNode(int value){
if(root->deleteNode(value))
cout << "刪除成功" <<endl;
else
cout << "刪除失敗" <<endl;
}
void inOrder(){
if(root != NULL)
root->inOrder();
}
};
int main(){
BinaryTree binarytree;
int arr[] = {-111, 0, 22, 4, 3, 8, -2, -11, 123, 2333, 44, 9, 100};
for(int i=0; i<13; i++)
binarytree.myInsert(arr[i]);
binarytree.inOrder();
cout<<endl;
binarytree.mySearch(2333);
binarytree.mySearch(-2333);
binarytree.deleteNode(100);
binarytree.inOrder();
cout<<endl;
system("pause");
return 0;
}
如有疑問或錯誤,歡迎提出,謝謝