1. 程式人生 > >二叉排序樹的結點刪除

二叉排序樹的結點刪除

      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; }

如有疑問或錯誤,歡迎提出,謝謝