搜索二叉树的增删查改

来源:互联网 发布:电话营销数据库 编辑:程序博客网 时间:2024/05/22 17:21
    首先我简单介绍一下搜索二叉树的概念及有关性质,纯属个人观点,如有错误,欢迎不吝赐教。
1、搜索二叉树的概念:根结点的左子树都小于它,它的右子树都大于它,且它的左子树与右子树都是搜素二叉树。
2、二叉搜索树(搜索二叉树):搜索二叉树即是排序二叉树,中序遍历它的结果是有序的(升序)。
3、二叉搜索树的性质
  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();
}
1 0
原创粉丝点击