搜索二叉樹的增刪查改

    首先我簡單介紹一下搜索二叉樹的概念及有關性質,純屬個人觀點,如有錯誤,歡迎不吝賜教。
1、搜索二叉樹的概念:根結點的左子樹都小於它,它的右子樹都大於它,且它的左子樹與右子樹都是搜素二叉樹。
2、二叉搜索樹(搜索二叉樹):搜索二叉樹即是排序二叉樹,中序遍歷它的結果是有序的(升序)。
  1. 每個節點都有一個作爲搜索依據的關鍵碼(key),所有節點的關鍵碼互不相同。
  2. 左子樹上所有節點的關鍵碼(key)都小於根節點的關鍵碼(key)。
  3. 右子樹上所有節點的關鍵碼(key)都大於根節點的關鍵碼(key)。
  4. 左右子樹都是二叉搜索樹。
搜索二叉樹的非遞歸插入:
     思想:
代碼如下:
//非遞歸插入
          boolInsert(constK&key,constV&value)
          {
                   if(_root ==NULL)
                   {
                             _root =newNode(key,value);
                             returntrue;
                   }

                   Node* parent =NULL;
                   Node* cur = _root;
                   while(cur)
                   {
                             if(cur->_key <key)
                             {
                                      parent = cur;
                                      cur = cur->_right;
                             }
                             elseif(cur->_key >key)
                             {
                                      parent = cur;
                                      cur = cur->_left;
                             }
                             else
                             {
                                      returnfalse;
                             }
                   }

                   if(parent->_key <key)
                             parent->_right =newNode(key,value);
                   else
                             parent->_left =newNode(key,value);

                   returntrue;
          }
遞歸插入算法如下:
//遞歸插入
          boolInsertR(constK&key,constV&value)
          {
                   return_InsertR(_root,key,value);
          }

          bool_InsertR(Node*&root,constK&key,constV&value)
          {
                   if(root==NULL)
                   {
                             root=newNode(key,value);
                             returntrue;
                   }

                   if(root->_key >key)
                             return_InsertR(root->_left,key,value);
                   elseif(root->_key < key)
                             return_InsertR(root->_right,key,value);
                   else
                             returnfalse;
          }
查找指定節點(非遞歸方法):
Node* Find(constK&key)
          {
                   Node* cur = _root;
                   while(cur)
                   {
                             if(cur->_key <key)
                             {
                                      cur = cur->_right;
                             }
                             elseif(cur->_key >key)
                             {
                                      cur = cur->_left;
                             }
                             else
                             {
                                      returncur;
                             }
                   }

                   returnNULL;
          }
遞歸方法查找指定的節點:
Node* Find(constK&key)
          {
                   Node* cur = _root;
                   while(cur)
                   {
                             if(cur->_key <key)
                             {
                                      cur = cur->_right;
                             }
                             elseif(cur->_key >key)
                             {
                                      cur = cur->_left;
                             }
                             else
                             {
                                      returncur;
                             }
                   }

                   returnNULL;
          }
刪除指定節點(非遞歸方法):


//刪除指定節點
          boolRemove(constK&key)
          {
                   Node* parent =NULL;
                   Node* cur = _root;
                   //cur不爲空
                   while(cur)
                   {
                             if(cur->_key <key)
                             {
                                      parent = cur;
                                      cur = cur->_right;
                             }
                             elseif(cur->_key >key)
                             {
                                      parent = cur;
                                      cur = cur->_left;
                             }
                             else
                             {
                                      break;//相等時直接break掉
                             }
                   }
                   //cur爲空時,沒有找到指定刪除的節點,返回false
                   if(cur ==NULL)
                   {
                             returnfalse;
                   }
                   //cur的左子樹爲空
                   if(cur->_left ==NULL)
                   {
                             //parent==NULL,說明cur是根節點,要刪除cur(由上步可知cur的左子樹爲空),所以要刪除cur,只需要讓_root指向cur->right即可。
                             if(parent ==NULL)
                             {
                                      _root = cur->_right;
                             }
                             else
                             {
                                      if(parent->_left == cur)
                                                parent->_left = cur->_right;
                                      else
                                                parent->_right = cur->_right;
                             }

                             deletecur;
                   }
                   elseif(cur->_right ==NULL)
                   {
                             if(parent ==NULL)
                             {
                                      _root = cur->_left;
                             }
                             else
                             {
                                      if(parent->_left == cur)
                                                parent->_left = cur->_left;
                                      else
                                                parent->_right = cur->_left;
                             }

                             deletecur;
                   }
                   else
                   {
                             // 找右子樹裏面的最左結點
                             parent = cur;
                             Node* subLeft = cur->_right;
                             while(subLeft->_left)
                             {
                                      parent = subLeft;
                                      subLeft = subLeft->_left;
                             }

                             cur->_key = subLeft->_key;
                             cur->_value = subLeft->_value;

                             if(parent->_left == subLeft)
                                      parent->_left = subLeft->_right;
                             else
                                      parent->_right = subLeft->_right;

                             deletesubLeft;
                   }

                   returntrue;
          }
遞歸刪除:
//遞歸刪除
          boolRemoveR(constK&key)
          {
                   return_RemoveR(_root,key);
          }

          bool_RemoveR(Node*&root,constK&key)
          {
                   if(root==NULL)
                             returnfalse;

                   if(root->_key >key)
                   {
                             return_RemoveR(root->_left,key);
                   }
                   elseif(root->_key < key)
                   {
                             return_RemoveR(root->_right,key);
                   }
                   else
                   {
                             if(root->_left ==NULL)
                             {
                                      root=root->_right;
                             }
                             elseif(root->_right == NULL)
                             {
                                      root=root->_left;
                             }
                             else
                             {
                             }
                   }

                   returntrue;
          }

附錄(具體代碼實現如下):
#pragma once
#include<iostream>
#include<string>
template<class K,class V>
//構造搜索化二叉樹結構體
struct BSTreeNode
{
K _key;
V _value;
BSTreeNode<K, V> *_left;
BSTreeNode<K, V> *_right;


//構造函數
BSTreeNode(const K& key,const V& value)
:_key(key)
,_value(value)
,_left(NULL)
,_right(NULL)
{}
};


template<class K, class V>
class BSTree
{
typedef BSTreeNode<K, V> Node;
public:
BSTree()
:_root(NULL)
{}
//非遞歸插入
bool Insert(const K& key, const V& value)
{
if (_root == NULL)
{
_root = new Node(key, value);
return true;
}


Node* parent = NULL;
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else
{
return false;
}
}


if (parent->_key < key)
parent->_right = new Node(key, value);
else
parent->_left = new Node(key, value);


return true;
}
//遞歸插入
bool InsertR(const K& key, const V& value)
{
return _InsertR(_root, key, value);
}


bool _InsertR(Node*& root, const K& key, const V& value)
{
if (root == NULL)
{
root = new Node(key, value);
return true;
}


if (root->_key > key)
return _InsertR(root->_left, key, value);
else if (root->_key < key)
return _InsertR(root->_right, key, value);
else
return false;
}


Node* Find(const K& key)
{
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
cur = cur->_right;
}
else if (cur->_key > key)
{
cur = cur->_left;
}
else
{
return cur;
}
}


return NULL;
}


Node* FindR(const K& key)
{
return _FindR(key);
}


Node* _FindR(Node* root, const K& key)
{
if (root == NULL)
{
return NULL;
}


if (root->_key < key)
{
return _FindR(root->_right, key);
}
else if (root->_key > key)
{
return _FindR(root->_left, key);
}
else
{
return root;
}
}
//刪除指定節點
bool Remove(const K& key)
{
Node* parent = NULL;
Node* cur = _root;
//cur不爲空
while (cur)
{
if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else
{
break;//相等時直接break掉
}
}
//cur爲空時,沒有找到指定刪除的節點,返回false
if (cur == NULL)
{
return false;
}
//cur的左子樹爲空
if (cur->_left == NULL)
{
//parent==NULL,說明cur是根節點,要刪除cur(由上步可知cur的左子樹爲空),所以要刪除cur,只需要讓_root指向cur->right即可。
if (parent == NULL)
{
_root = cur->_right;
}
else
{
if (parent->_left == cur)
parent->_left = cur->_right;
else
parent->_right = cur->_right;
}


delete cur;
}
else if (cur->_right == NULL)
{
if (parent == NULL)
{
_root = cur->_left;
}
else
{
if (parent->_left == cur)
parent->_left = cur->_left;
else
parent->_right = cur->_left;
}


delete cur;
}
else
{
// 找右子樹裏面的最左結點
parent = cur;
Node* subLeft = cur->_right;
while (subLeft->_left)
{
parent = subLeft;
subLeft = subLeft->_left;
}


cur->_key = subLeft->_key;
cur->_value = subLeft->_value;


if (parent->_left == subLeft)
parent->_left = subLeft->_right;
else
parent->_right = subLeft->_right;


delete subLeft;
}


return true;
}
//遞歸刪除
bool RemoveR(const K& key)
{
return _RemoveR(_root, key);
}


bool _RemoveR(Node*& root, const K& key)
{
if (root == NULL)
return false;


if (root->_key > key)
{
return _RemoveR(root->_left, key);
}
else if (root->_key < key)
{
return _RemoveR(root->_right, key);
}
else
{
if (root->_left == NULL)
{
root = root->_right;
}
else if (root->_right == NULL)
{
root = root->_left;
}
else
{
}
}


return true;
}
//中序遍歷
void InOrder()
{
_InOrder(_root);
cout << endl;
}


void _InOrder(Node* root)
{
if (root == NULL)
return;
        }

protected:
Node* _root;
};


void TestTree()
{
BSTree<int, int> t;
int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
{
t.Insert(a[i], i);
}
t.InOrder();


cout << "IsBlance?" << t.IsBlanceTree() << endl;


t.Remove(8);
t.Remove(7);
t.Remove(2);
t.Remove(1);


t.InOrder();


t.Remove(0);
t.Remove(1);
t.Remove(2);
t.Remove(3);
t.Remove(4);
t.Remove(5);
t.Remove(6);
t.Remove(7);
t.Remove(8);
t.Remove(9);


t.InOrder();
}


void TestDict()
{
BSTree<string, string> dict;
dict.Insert("Tree", "樹");
dict.Insert("Sort", "哈希");
dict.Insert("Hash", "排序");
dict.InOrder();


BSTreeNode<string, string>* ret = dict.Find("Sort");
ret->_value = "排序";


ret = dict.Find("Hash");
ret->_value = "哈希";


dict.InOrder();
}
發佈了40 篇原創文章 · 獲贊 29 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章