二叉搜索树的增删查改

本文深入探讨了二叉搜索树的基础知识,重点讲解了如何在二叉搜索树中进行插入、删除、查找和修改操作。通过理解这些操作,可以更好地掌握数据结构中的平衡搜索树原理。
摘要由CSDN通过智能技术生成

二叉搜索树注重增删查改,现在针对key/value形式进行研究。

现在对其进行实现,分别有插入,查找,删除,分别对这几个功能用递归和非递归实现。           其中删除操作比较特别,分为 3种,分别是删除叶子节点,删除左为空或右为空的节点, 第三种是删除左右子树都不为空的节点。最后一种删除最麻烦,它分为三个步骤,分别是找出右树的最左节点,然后和要删除的节点进行key/value的互换,然后再删除它最左节点。

代码实现:
template<class K,class V>
struct BinarySearchTreeNode //key/value形式
{
                BinarySearchTreeNode( const K & key, const V& value)
                :_key( key)
                , _value( value)
                , _left( NULL)
                , _right( NULL)
                {}
                 K _key;
                 V _value;
                 BinarySearchTreeNode<K , V>* _left;
                 BinarySearchTreeNode<K , V>* _right;
};

template<class K, class V>
class BinarySearchTree
{
                 typedef BinarySearchTreeNode <K, V> Node;
public:
                BinarySearchTree()
                                :_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 (key < cur->_key)
                                                {
                                                                parent = cur;
                                                                cur = cur->_left;
                                                }
                                                 else if (key>cur->_key)
                                                {
                                                                parent = cur;
                                                                cur = cur->_right;
                                                }
                                                 else
                                                                 return false ;
                                }
                                 if (parent->_key > key )
                                                parent->_left = new Node (key, value);
                                 else
                                                parent->_right = new Node (key, value);
                                 return true ;            
                }

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

                 Node* Find(const K& key)//查找(非递归)
                {
                                 if (_root == NULL )
                                                 return NULL ;
                                
                                 Node* cur = _root;
                                 while (cur)
                                {
                                                 if (cur->_key == key )
                                                                 return cur;
                                                 else if (key < cur->_key)
                                                                cur = cur->_left;
                                                 else
                                                                cur = cur->_right;
                                }
                                 return NULL ;
                }

                 Node* FindR(const V& key)//插入(递归)
                {
                                 return _FindR(_root, key );
                }

                 bool Remove(const K& key)//删除节点(非递归)
                {
                                 if (_root == NULL )
                                                 return false ;
                                
                                 Node* cur = _root;
                                 Node* parent=NULL ;
                                 while (cur)
                                {
                                                 if (key < cur->_key)
                                                {
                                                                parent = cur;
                                                                cur = cur->_left;
                                                }
                                                 else if (key>cur->_key)
                                                {
                                                                parent = cur;
                                                                cur = cur->_right;
                                                }              
                                                 else//找到节点
                                                {
                                                                 if (cur->_left == NULL &&cur->_right == NULL)//叶子节点
                                                                {
                                                                                 Node* del = cur;
                                                                                 delete del;
                                                                                del = NULL;
                                                                                 return true ;
                                                                }

                                                                 else if (cur->_left == NULL||cur->_right == NULL)//右树或左树为空
                                                                {
                                                                                 Node* del = cur;
                                                                                 if (parent->_right==cur)
                                                                                {
                                                                                                 if (cur->_right == NULL )
                                                                                                {
                                                                                                                parent->_right = cur->_left;
                                                                                                                 delete del;
                                                                                                                del = NULL;
                                                                                                                 return true ;
                                                                                                }
                                                                                                 else if (cur->_left == NULL)
                                                                                                {
                                                                                                                parent->_right = cur->_right;
                                                                                                                 delete del;
                                                                                                                del = NULL;
                                                                                                                 return true ;
                                                                                                }
                                                                                }
                                                                                 else if (parent->_left==cur)
                                                                                {
                                                                                                 Node* del = cur;
                                                                                                 if (cur->_left == NULL )
                                                                                                {
                                                                                                                parent->_left = cur->_right;
                                                                                                                 delete del;
                                                                                                                del = NULL;
                                                                                                                 return true ;
                                                                                                }
                                                                                                 else if (cur->_right == NULL)
                                                                                                {
                                                                                                                parent->_left = cur->_left;
                                                                                                                 delete del;
                                                                                                                del = NULL;
                                                                                                                 return true ;
                                                                                                }
                                                                                }
                                                                }
                                                                 if (cur->_left != NULL &&cur->_right != NULL)//左树和右树都不为空
                                                                {
                                                                                 Node* parent = cur;
                                                                                 Node* FirstLeft = cur->_right;
                                                                                 while (FirstLeft->_left)//找右树的最左节点
                                                                                {
                                                                                                parent = FirstLeft;
                                                                                                FirstLeft = FirstLeft->_left;
                                                                                }

                                                                                swap(cur->_key, FirstLeft->_key);//交换
                                                                                swap(cur->_value, FirstLeft->_value);
                                                                                 Node* del = FirstLeft;
                                                                                 if (parent->_left==FirstLeft)
                                                                                                parent->_left = FirstLeft->_right;
                                                                                 else
                                                                                                parent->_right = FirstLeft->_right;
                                                                                 delete del;
                                                                                del = NULL;
                                                                                 return true ;
                                                                }                                              
                                                }
                                }
                                 return false ;//未找到要删除的节点
                }

                 bool RemoveR(const K& key)//删除(递归)
                {
                                 return _RemoveR(_root,key );
                }

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

protected:
                 bool _RemoveR(Node *& root,const  K& key )//删除会修改_root,用引用
                {
                                 if (root == NULL)
                                                 return false ;
                
                                 if (key < root->_key)
                                                _RemoveR( root->_left, key );
                                 else if (key> root->_key)
                                                _RemoveR( root->_right, key );
                                 else//相等
                                {
                                                 if (root ->_right == NULL)//右子树为空
                                                {
                                                                 root = root ->_left;
                                                                 delete root ;
                                                                 root = NULL ;
                                                                 return true ;
                                                }
                                                 else if (root->_left == NULL)//左子树为空
                                                {
                                                                 root = root ->_right;
                                                                 delete root ;
                                                                 root = NULL ;
                                                                 return true ;
                                                }
                                                 else//左右子树都不为空
                                                {
                                                                 Node* FirstLeft = root ->_right;
                                                                 Node* parent = root ;
                                                                 while (FirstLeft->_left)//找最左节点
                                                                {
                                                                                parent = FirstLeft;
                                                                                FirstLeft = FirstLeft->_left;
                                                                }

                                                                swap( root->_key, FirstLeft->_key);//交换
                                                                swap( root->_value, FirstLeft->_value);
                                                                _RemoveR( root->_right, key );//继续递归右树的最左节点
                                                }
                                }
                }

                 bool _InsertR(Node *& root,const K& key,const V& value)//添加会修改_root,所以用引用
                {
                                 if (root == NULL)
                                {
                                                 root = new Node(key, value);
                                                 return true ;
                                }
                                 if (key < root->_key)
                                                _InsertR( root->_left, key , value);
                                 else if (key> root->_key)
                                                _InsertR( root->_right, key , value);
                                 else//相等
                                                 return false ;

                }

                 Node* _FindR(Node * root, const K& key)//查找
                {
                                 if (root == NULL)
                                                 return NULL ;
                                 if (root ->_key == key)
                                                 return root ;
                                 else if (key < root->_key)
                                                _FindR( root->_left, key );
                                 else
                                                _FindR( root->_right, key );
                }

                 void _InOrder(Node * root)//中序递归写法
                {
                                 if (root == NULL)
                                                 return;
                                
                                                _InOrder( root->_left);
                                                cout << root->_value << " " ;
                                                _InOrder( root->_right);
                }
private:
                 Node* _root;
};
/*******************************************************************************************************************************************/
void test11()
{
                 BinarySearchTree<int , int> s1; //实现key/value形式的搜索树
                 int arr[10] = { 5, 3,1, 7 };
                 for (int i = 0; i < 4; i++)
                {
                                s1.Insert(arr[i], i);
                }

                 //s1.InOrder();

                 //cout << s1.Find(4)->_value << endl;
                 //cout << s1.Find(5)->_value << endl;
                 //cout << s1.Find(7)->_value << endl;

                 //s1.Remove(7);
                 //s1.Remove(3);
                
                
                 //s1.Remove(5);
                 //s1.InOrder();

                cout << s1.FindR(1)->_value << endl;
}

void test2()
{
                 BinarySearchTree<int , int> s1; //实现key/value形式的搜索树
                 int arr[10] = { 5, 3, 1, 7 };
                 for (int i = 0; i < 4; i++)
                {
                                s1.InsertR(arr[i], i);
                }

                 //s1.InOrder();

                s1.RemoveR(1);
                s1.InOrder();
                s1.RemoveR(5);
                s1.InOrder();
}


二叉搜索树存在缺陷,就是左右分布十分不均匀,这样造成二叉搜索树的退化
例如:

需要解决这个问题就是平衡搜索树。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C++实现二叉搜索树增删查改的示例代码: 1. 结点类的实现: ```c++ class Node { public: int val; Node* left; Node* right; Node(int val) { this->val = val; this->left = nullptr; this->right = nullptr; } }; ``` 2. 二叉搜索树类的实现: ```c++ class BST { public: Node* root; BST() { root = nullptr; } // 插入操作 void insert(int val) { root = insertNode(root, val); } // 删除操作 void remove(int val) { root = removeNode(root, val); } // 查找操作 bool search(int val) { return searchNode(root, val); } // 修改操作 void modify(int oldVal, int newVal) { remove(oldVal); insert(newVal); } private: // 插入结点 Node* insertNode(Node* node, int val) { if (node == nullptr) { return new Node(val); } if (val < node->val) { node->left = insertNode(node->left, val); } else if (val > node->val) { node->right = insertNode(node->right, val); } return node; } // 删除结点 Node* removeNode(Node* node, int val) { if (node == nullptr) { return nullptr; } if (val < node->val) { node->left = removeNode(node->left, val); } else if (val > node->val) { node->right = removeNode(node->right, val); } else { if (node->left == nullptr && node->right == nullptr) { delete node; node = nullptr; } else if (node->left == nullptr) { Node* temp = node; node = node->right; delete temp; } else if (node->right == nullptr) { Node* temp = node; node = node->left; delete temp; } else { Node* temp = findMin(node->right); node->val = temp->val; node->right = removeNode(node->right, temp->val); } } return node; } // 查找结点 bool searchNode(Node* node, int val) { if (node == nullptr) { return false; } if (val == node->val) { return true; } else if (val < node->val) { return searchNode(node->left, val); } else { return searchNode(node->right, val); } } // 查找最小值 Node* findMin(Node* node) { while (node->left != nullptr) { node = node->left; } return node; } }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值