zoukankan      html  css  js  c++  java
  • 一个简易的元素不重复的二叉搜索树链表的实现

    不知道为什么, 之前好几篇博客都被一些不出名的小网站抄了。 其实我写这些博客的目的是练手, 但是当知道被人抄了而自己却毫不知情, 还是有些蛋疼的。

    代码如下:

      1 struct TreeNode;
      2 typedef shared_ptr<TreeNode> PTreeNode;
      3 
      4 struct TreeNode
      5 {
      6     int32_t              key        = 0;
      7     PTreeNode            leftChild   = nullptr;
      8     PTreeNode            rightChild  = nullptr;
      9 
     10     // 此处若设为 shared_ptr, 则会导致循环引用.
     11     weak_ptr<TreeNode>   parent;
     12 
     13     PTreeNode& MoveToNextNode (const int32_t& value)
     14     {
     15         return key < value ? rightChild : leftChild;
     16     }
     17 };
     18 
     19 class BinarySearchTree
     20 {
     21 private:
     22     PTreeNode   root;
     23 
     24     PTreeNode MakeNewNode (const int32_t& value)
     25     {
     26         auto newNode = make_shared<TreeNode> ();
     27         newNode->key = value;
     28         return newNode;
     29     }
     30     enum Direction { left, right };
     31     PTreeNode GetEdgeNode (PTreeNode node, const Direction&);
     32     // Return the node which the key is lowest but greater than parm node.
     33     PTreeNode Successor   (PTreeNode);
     34     bool IsLeftChild      (const PTreeNode& node)
     35     {
     36         return node->parent.lock ()->leftChild == node;
     37     }
     38     void TransferParent   (const PTreeNode&, const PTreeNode&);
     39 public:
     40     PTreeNode MaxNode (PTreeNode node = nullptr)
     41     {
     42         if (node == nullptr) {
     43             node = root;
     44         }
     45         return GetEdgeNode (node, right);
     46     }
     47     PTreeNode MinNode (PTreeNode node = nullptr)
     48     {
     49         if (node == nullptr) {
     50             node = root;
     51         }
     52         return GetEdgeNode (node, left);
     53     }
     54     PTreeNode Search (const int32_t&);
     55     void      Insert (const int32_t&);
     56     void      Delete (const int32_t&);
     57 };
     58 
     59 void      BinarySearchTree::TransferParent  (const PTreeNode& parent, const PTreeNode& child)
     60 {
     61     if (child != nullptr) {
     62         child->parent = parent->parent;
     63     }
     64 
     65     // The target node is root.
     66     if (parent->parent.expired ()) {
     67         root = child;
     68     }
     69     else {
     70         if (IsLeftChild (parent)) {
     71             parent->parent.lock ()->leftChild = child;
     72         }
     73         else {
     74             parent->parent.lock ()->rightChild = child;
     75         }
     76     }
     77 }
     78 PTreeNode BinarySearchTree::GetEdgeNode     (PTreeNode node, const Direction& dir)
     79 {
     80     auto result = node;
     81     auto NextNode = [&] ()
     82     {
     83         if (dir == left) {
     84             return result->leftChild;
     85         }
     86         else {
     87             return result->rightChild;
     88         }
     89     };
     90 
     91     while (NextNode () != nullptr) {
     92         result = NextNode ();
     93     }
     94     return result;
     95 }
     96 PTreeNode BinarySearchTree::Successor       (PTreeNode node)
     97 {
     98     // If the node has right subtree, return the min of the right subtree.
     99     if (node->rightChild != nullptr) {
    100         return MinNode (node->rightChild);
    101     }
    102 
    103     // Otherwise the node has the greatest key in it's subtree.
    104     auto currentParent = node->parent.lock ();
    105 
    106     // Search upward, until get a node 
    107     // which the left child is the head of the subtree that the node stay in.
    108     while (currentParent != nullptr && node == currentParent->rightChild) {
    109         node = currentParent;
    110         currentParent = currentParent->parent.lock ();
    111     }
    112 
    113     // And return that node.
    114     return currentParent;
    115 }
    116 PTreeNode BinarySearchTree::Search          (const int32_t& value)
    117 {
    118     auto current = root;
    119     while (current != nullptr && current->key != value) {
    120         current = current->MoveToNextNode (value);
    121     }
    122     return current;
    123 }
    124 void      BinarySearchTree::Insert          (const int32_t& value)
    125 {
    126     auto result = Search (value);
    127     if (result != nullptr) {
    128         cerr << "The" << value << "already exist!
    ";
    129         return;
    130     }
    131 
    132     if (root == nullptr) {
    133         root = MakeNewNode (value);
    134     }
    135     else {
    136         auto current = root;
    137         while (true) {
    138             auto& p =
    139                 current->MoveToNextNode (value);
    140             if (p == nullptr) {
    141                 p = MakeNewNode (value);
    142                 p->parent = current;
    143                 break;
    144             }
    145             current = p;
    146         }
    147     }
    148 }
    149 void      BinarySearchTree::Delete          (const int32_t& value)
    150 {
    151     auto node = Search (value);
    152     if (node == nullptr) {
    153         cerr << "There is no such value!
    ";
    154         return;
    155     }
    156 
    157     // Don't have any child.
    158     if (node->leftChild == nullptr && node->rightChild == nullptr) {
    159         auto parent = (node->parent).lock ();
    160         if (IsLeftChild (node)) {
    161             parent->leftChild = nullptr;
    162         }
    163         else {
    164             parent->rightChild = nullptr;
    165         }
    166     }
    167 
    168     // Have double child.
    169     else if (node->leftChild != nullptr && node->rightChild != nullptr) {
    170         // Find successor
    171         auto successor = Successor (node);
    172 
    173         // Delete successor from it's subtree.
    174         TransferParent (successor, successor->rightChild);
    175 
    176         // Replace the node.
    177         node->key = successor->key;
    178     }
    179 
    180     // Have single child.
    181     else {
    182         if (node->leftChild != nullptr) {
    183             TransferParent (node, node->leftChild);
    184         }
    185         else {
    186             TransferParent (node, node->rightChild);
    187         }
    188     }
    189 }
  • 相关阅读:
    Oracle查看正在执行的存储过程的sid---转
    使用WITH子句重用子查询
    oracle解决显示数据的层次问题--实现数据缩进
    oracle9i、10g、11g区别 --转
    oracle10g安装在裸设备上
    在Linux系统上面创建使用裸设备的数据库
    监控Oracle数据库的常用shell脚本-转
    sql server使用维护计划定时备份完整数据库、差异数据库
    使用Advanced Installer14.3 简单打包windows窗体应用程序
    SVG Path标签 A 参数
  • 原文地址:https://www.cnblogs.com/wuOverflow/p/4309396.html
Copyright © 2011-2022 走看看