利用包装器以及lambda表达式实现二叉查找树

二叉查找树的实现与操作
本文详细介绍了二叉查找树的实现方法,包括插入、遍历、查找、删除和更新节点的操作,并通过实例展示了如何使用二叉查找树进行数据存储与检索。

#include<iostream>
#include<functional>
using namespace std;


template <class T>
class tree
{
private:
 struct Node
 {
  T data;
  Node* L;
  Node* R;
  Node(T d) :data(d), L(NULL), R(NULL){}
 };
 Node* root;
 int Count;
public:
 tree() :root(NULL), Count(0){}
 tree& Insert(T d)
 {
  function<tree&(Node*&, T&)> ins = [&](Node*& r, T& dd)->tree&
  {
   if (r == NULL)
   {
    r = new Node(dd);
    return *this;
   }
   else if (dd < r->data)
   {
    return ins(r->L, dd);
   }
   else
   {
    return ins(r->R, dd);
   }
  };
  Count++;
  return ins(root, d);
 }
 void Travel()
 {
  function<void(Node*&)> tra = [&](Node*& r)
  {
   if (r == NULL)
   {
    return;
   }
   tra(r->L);
   cout << r->data << " ";
   tra(r->R);
  };
  tra(root);
 }
 Node*& Find(T d)
 {
  function<Node*&(Node*&, T)> fid = [&](Node*& r, T dd)->Node*&
  {
   if (r == NULL)
   {
    return r;
   }
   else if (r->data == dd)
   {
    return r;
   }
   else if (r->data < dd)
   {
    return fid(r->R, dd);
   }
   else
   {
    return fid(r->L, dd);
   }
  };
  return fid(root, d);
 }
 bool If_empty()
 {
  return root == NULL;
 }
 bool Remove(T d)
 {
  function<bool(Node*, T)> rem = [&](Node* r, T dd)
  {
   Node*& temp = Find(dd);
   if (temp == NULL)
   {
    return false;
   }
   Node* p = temp;
   if (temp->L)
   {
    //无论有没有右子树,都不用考虑
    Node* pn = temp->R;
    while (pn->L)
    {
     pn = pn->L;
    }
    pn->L = temp->L;
   }
   temp = temp->R;
   delete p;
   p = NULL;
   return true;
  };
  return rem(root, d);
 }
 void updata(T d)
 {
  Insert(d);
 }
 void clear()
 {
  function<void(Node*&)> cls = [&](Node*& r)
  {
   if (r == NULL)
   {
    return;
   }
   cls(r->L);
   cls(r->R);
   delete r;
   r = NULL;
  };
  cls(root);
 }
 int high()
 {
  function<int(Node*)> h = [&](Node* r)
  {
   if (r == NULL)
   {
    return 0;
   }
   int lh = h(r->L);
   int rh = h(r->R);
   return 1 + (lh > rh ? lh : rh);
  };
  return h(root);
 }
};


int main()
{
 tree<int> t;
 t.Insert(5);
 t.Insert(2);
 t.Insert(1);
 t.Insert(3);
 t.Insert(6);
 t.Insert(4);
 t.Travel();
 cout << endl;
 t.Remove(2);
 t.Travel();

 cin.get();
 return 0;
}


### C++ 实现二叉搜索树 (Binary Search Tree, BST) 以下是基于提供的引用以及专业知识,详细介绍如何用 C++ 构建二叉搜索树的教程和示例代码。 #### 结点类设计 为了表示二叉搜索树中的每一个节点,可以创建一个模板化的 `Node` 类型。该类型包含三个主要成员变量:键值 `_key` 和指向左右子节点的指针 `_left` 及 `_right`[^1]。 ```cpp template<class K> struct Node { Node(const K& val) : _left(nullptr), _right(nullptr), _key(val) {} Node<K>* _left; Node<K>* _right; K _key; }; ``` 此部分实现了基础的数据结构定义,其中构造函数初始化了新节点并将其左右孩子设置为空指针[^2]。 --- #### 二叉搜索树类设计 接着,我们需要定义另一个模板化类 `BST` 来管理整个二叉搜索树的操作逻辑。这个类应提供插入、删除、查找等功能,并维护根节点 `_root` 的状态。 ```cpp template<class K> class BST { public: typedef Node<K> node; // 插入功能 void Insert(const K& key); // 查找功能 bool Find(const K& key) const; // 删除功能 void Remove(const K& key); private: node* _root; // 辅助递归函数 node* InsertHelper(node* root, const K& key); bool FindHelper(node* root, const K& key) const; node* RemoveHelper(node* root, const K& key); }; // 插入实现 template<class K> typename BST<K>::node* BST<K>::InsertHelper(node* root, const K& key) { if (!root) { return new node(key); // 如果当前节点为空,则新建节点返回 } if (key < root->_key) { root->_left = InsertHelper(root->_left, key); // 小于则进入左子树 } else if (key > root->_key) { root->_right = InsertHelper(root->_right, key); // 大于则进入右子树 } return root; // 返回调整后的根节点 } template<class K> void BST<K>::Insert(const K& key) { _root = InsertHelper(_root, key); } ``` 上述代码片段展示了如何通过递归方式完成节点的插入操作。当尝试向空位置插入时会动态分配内存;而其他情况下依据比较结果决定继续访问哪个分支。 --- #### 验证二叉搜索树的有效性 对于给定的一棵二叉树,判断其是否满足二叉搜索树性质的一种常见做法是利用 **中序遍历** 特性——即如果一棵树为合法的二叉搜索树,那么它的中序遍历序列应当严格单调递增[^4]。 下面给出一种简单的验证算法: ```cpp #include <vector> bool IsValidBST(Node<int>* root) { std::vector<int> inorderResult; std::function<void(Node<int>*)> InorderTraversal = [&](Node<int>* curr) -> void { if (!curr) return; InorderTraversal(curr->_left); inorderResult.push_back(curr->_key); InorderTraversal(curr->_right); }; InorderTraversal(root); for (size_t i = 1; i < inorderResult.size(); ++i) { if (inorderResult[i - 1] >= inorderResult[i]) { return false; // 若发现任何不满足条件的情况立即退出 } } return true; } ``` 这里采用了 Lambda 表达式简化内部调用过程,并借助辅助容器记录下完整的中序遍历路径以便后续逐一校验相邻两数之间的关系。 --- #### 转换为递增顺序搜索树 除了常规的功能外,有时还需要将现有的二叉搜索树转换成特定形式的新结构,比如让所有节点沿单一方向排列形成链表状的结果。这种变换可通过修改原树连接关系达成目标,具体步骤如下所示[^3]: ```cpp Node<int>* IncreasingOrderTree(Node<int>* root) { static Node<int>* prev = nullptr; if (!root) return nullptr; IncreasingOrderTree(root->_left); if (prev != nullptr) { prev->_right = root; root->_left = nullptr; } else { // 记录新的头结点 head = root; } prev = root; IncreasingOrderTree(root->_right); return head; } ``` 此处运用了静态局部变量保存前驱信息,在每次处理完某个节点之后更新全局头部指示器直至整棵树被完全重构完毕为止。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值