搜索二叉树的增删查改

    首先我简单介绍一下搜索二叉树的概念及有关性质,纯属个人观点,如有错误,欢迎不吝赐教。
1、搜索二叉树的概念:根结点的左子树都小于它,它的右子树都大于它,且它的左子树与右子树都是搜素二叉树。
2、二叉搜索树(搜索二叉树):搜索二叉树即是排序二叉树,中序遍历它的结果是有序的(升序)。
  1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
  2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
  3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
  4. 左右子树都是二叉搜索树。
搜索二叉树的非递归插入:
     思想:
代码如下:
//非递归插入
           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 * 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 ;
          }
删除指定节点(非递归方法):


//删除指定节点
           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 ;
          }

附录(具体代码实现如下):
#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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值