1. 程式人生 > >二叉搜索樹的簡易實現

二叉搜索樹的簡易實現

存在 替換 ear size 它的 刪除結點 樹的定義 操作 log

二叉查找樹或者是一棵空二叉樹;或者是具有下列性質的二叉樹:

(1)若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;

(2)若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值。 (3)根結點的左右子樹分別也是二叉查找樹。

二叉查找樹可以用來組織一組數據,並且實現在這組數據上的快速檢索。

二叉查找樹或者是一棵空二叉樹;或者是具有下列性質的二叉樹:

(1)若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;

(2)若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值。

(3)根結點的左右子樹分別也是二叉查找樹。

二叉查找樹可以用來組織一組數據,並且實現在這組數據上的快速檢索。

向二叉查找樹中插入新結點必須保證插入新結點後,二叉樹仍然滿足二叉查找樹的定義。

如何在二叉查找樹中插入新結點?

(1)若二叉查找樹為空,則新結點應作為二叉查找樹的根結點。

(2)將新結點的值和根結點的值比較,如果相等返回。(此時要插入的結點在樹中已存在)

(3)如果新結點的值小於根結點的值,則轉二叉查找樹的左子樹繼續插入操作。

(4)如果新結點的值大於根結點的值,則轉二叉查找樹的右子樹繼續插入操作。

從二叉查找樹上刪除結點應保證結點刪除後得到的二叉樹仍然是二叉查找樹。

如何從二叉查找樹中刪除結點?

(1)如果要刪除的結點是葉子結點,直接刪除並更新父結點指針。

(2)如果要刪除的結點只有一棵非空子樹,則令該非空子樹代替被刪除的結點作為被刪除結點父結點的相應子樹。

(3)如果要刪除的結點的兩棵子樹均非空,問題比較復雜,此時用要刪除結點的中序前趨替換要刪除的結點,再運用(1)和(2)中的方法刪除處在原來位置上的要刪除結點的中序前趨。而前驅結點是左子樹的右下角的那個結點。

下面是用C++實現的二叉搜索樹?

  1 template <typename Entry>
  2 class binary_tree
  3 {
  4     protected:
  5         //定義樹結點,方便訪問,不封裝,全部開放
  6         class binary_node
  7         {
  8             public
: 9 Entry data; //數據域 10 binary_node* lchild; //指向左子樹的指針域 11 binary_node* rchild; //指向右子樹的指針域 12 binary_node(){} //無參數構造函數 13 binary_node(const Entry& x):data(x),rchild(null),lchild(null){} //帶參數構造函數 14 }; 15 16 binary_node* root; //指向根結點的指針 17 18 public: 19 binary_tree(); 20 binary_tree(const binary_tree& bt); 21 virtual ~binary_tree(); 22 bool empty() const; 23 int size() const; 24 int height() const; 25 void clear(); 26 void preorder(binary_node*root,void(*visit)(Entry&)); 27 void inorder(binary_node*root,void(*visit)(Entry&)); 28 void postorder(binary_node*root,void(*visit)(Entry&)); 29 void level_traversal(binary_node*root,void(*visit)(Entry&)) 30 int insert(const Entry&); 31 int remove(const Entry&); 32 binary_tree& operator=(const binary_tree& bt); 33 34 }; 35 36 //二叉查找樹,普通二叉樹的基礎上寫 37 template <typename Entry> 38 class search_tree: public binary_tree 39 { 40 public: 41 int tree_search(Entry&) const; 42 int insert(const Entry&); 43 int remove(const Entry&); 44 45 }; 46 47 48 //按值查找結點 49 template <typename Entry> 50 search_tree<Entry>::binary_node<Entry>* search_for_node(binary_node* root,const Entry& target) 51 { 52 while(root->data != target && root != NULL) 53 if(root->data < target) root = root->rchild; 54 else root = root->lchild; 55 return root; 56 } 57 58 //查找,並且將找到的data放入傳入變量中 59 template <typename Entry> 60 int search_tree<Entry>::tree_search(const Entry& target) const 61 { 62 int result = 1; 63 binary_node* found = search_for_node(target); 64 if(found == NULL) result = 0; 65 else target = found->data; 66 return result; 67 } 68 69 70 //查找並且插入 71 template <typename Entry> 72 int search_tree<Entry>::search_and_insert(binary_node* root,const Entry& new_data) 73 { 74 if(root == NULL) 75 { 76 root = new binary_node(new_data); 77 return 1; 78 } 79 else if(new_data < root->data) 80 return search_and_insert(root->lchild,new_data); 81 else if(new_data > root->data) 82 return search_and_insert(root->rchild,new_data); 83 else return 0; 84 } 85 86 //插入操作 87 template <typename Entry> 88 int search_tree<Entry>::insert(const Entry& new_data) 89 { 90 return search_and_insert(root,new_data); 91 } 92 93 94 //刪除結點操作 95 template <typename Entry> 96 int search_tree<Entry>::remove_node(binary_node* node) 97 { 98 if(root == NULL) return 0; 99 if(node->rchild == NULL) node = node->lchild; 100 else if(node->lchild == NULL) node = node->rchild; 101 else 102 { 103 binary_node* parent = NULL; 104 binary_node* son = node->lchild; 105 /*找到要刪除結點的左子樹的最右下角的結點,即為待刪除結點的中序前驅結點*/ 106 while(temp->rchild != NULL) 107 { 108 parent = son; 109 son = son->rchild; 110 } 111 //parent是前驅結點的父節點,待刪除結點的前驅結點為子節點son。 112 node->data = son->data; //將前驅結點放到待刪除結點的位置 113 if(son->lchild != NULL) //刪除前驅結點 114 { 115 son->data = son->lchild->data; 116 delete son-lchild; 117 } 118 119 } 120 return 1; 121 122 } 123 124 //查找並且刪除 125 template <typename Entry> 126 int search_tree <Entry>::search_and_destroy(binary_node* root,const Entry& target) 127 { 128 if(root == NULL || root->data == target) 129 return remove_node(root); 130 else if(root->data < target) 131 search_and_destroy(root->rchild,target); 132 else search_and_destroy(root->lchild,target); 133 } 134 135 136 //刪除操作 137 template <typename Entry> 138 int search_tree<Entry>::remove(const Entry& target) 139 { 140 return search_and_destroy(root,target); 141 }

二叉搜索樹的簡易實現