• 《数据结构与算法分析:C语言描述》复习——第四章“树”——二叉搜索树


    2014.06.14 23:27

    简介:

      二叉搜索树是学习二叉树之后,接触的第一个实用数据结构。特点是,左子树全部小于根,右子树全部大于根,元素不重复。一般能够支持对数级别的增删改查操作,但在二叉树发生倾斜的情况下,效率会下降至线性。下面给出插入、删除、查找的示意图。修改可以认为是先删除后插入。

    图示:

      

      

      

      

      

      

    实现:

      1 // My implementation for binary search tree.
      2 #include <iostream>
      3 #include <string>
      4 #include <sstream>
      5 using namespace std;
      6 
      7 struct TreeNode {
      8     int val;
      9     TreeNode *left;
     10     TreeNode *right;
     11     TreeNode(int _val): val(_val), left(nullptr), right(nullptr) {};
     12 };
     13 
     14 class BinarySearchTree {
     15 public:
     16     BinarySearchTree() {
     17         m_root = nullptr;
     18     }
     19     
     20     bool empty() {
     21         return m_root == nullptr;
     22     }
     23     
     24     void clear() {
     25         _deleteTree(m_root);
     26     }
     27     
     28     void insertNode(const int &val) {
     29         if (m_root == nullptr) {
     30             m_root = new TreeNode(val);
     31             return;
     32         }
     33         TreeNode *ptr = _findNode(val);
     34         if (val < ptr->val) {
     35             ptr->left = new TreeNode(val);
     36         } else if (val > ptr->val) {
     37             ptr->right = new TreeNode(val);
     38         }
     39     }
     40     
     41     void deleteNode(const int &val) {
     42         if (m_root == nullptr) {
     43             return;
     44         }
     45         
     46         TreeNode *par, *cur;
     47         
     48         par = nullptr;
     49         cur = m_root;
     50         while (cur != nullptr) {
     51             if (val < cur->val) {
     52                 par = cur;
     53                 cur = cur->left;
     54             } else if (val > cur->val) {
     55                 par = cur;
     56                 cur = cur->right;
     57             } else {
     58                 break;
     59             }
     60         }
     61         
     62         if (cur == nullptr) {
     63             return;
     64         }
     65         
     66         if (cur->left != nullptr) {
     67             _shiftLeft(cur);
     68             return;
     69         }
     70         
     71         if (cur->right != nullptr) {
     72             _shiftRight(cur);
     73             return;
     74         }
     75         
     76         if (par == nullptr) {
     77             delete cur;
     78             m_root = nullptr;
     79         } else if (cur == par->left) {
     80             delete cur;
     81             par->left = nullptr;
     82         } else {
     83             delete cur;
     84             par->right = nullptr;
     85         }
     86     }
     87     
     88     void updateNode(const int &old_val, const int &new_val) {
     89         deleteNode(old_val);
     90         insertNode(new_val);
     91     }
     92     
     93     bool contains(const int &val) {
     94         TreeNode *ptr = _findNode(val);
     95         return ptr == nullptr ? false : ptr->val == val ? true : false;
     96     }
     97     
     98     string preorderTraversal() {
     99         string result;
    100         _preorderTraversalRecursive(m_root, result);
    101         return result;
    102     }
    103     
    104     string inorderTraversal() {
    105         string result;
    106         _inorderTraversalRecursive(m_root, result);
    107         return result;
    108     }
    109     
    110     string postorderTraversal() {
    111         string result;
    112         _postorderTraversalRecursive(m_root, result);
    113         return result;
    114     }
    115     
    116     ~BinarySearchTree() {
    117         clear();
    118     }
    119 private:
    120     TreeNode *m_root;
    121     
    122     void _deleteTree(TreeNode *&root) {
    123         if (root == nullptr) {
    124             return;
    125         }
    126         _deleteTree(root->left);
    127         _deleteTree(root->right);
    128         delete root;
    129         root = nullptr;
    130     }
    131     
    132     TreeNode* _findNode(const int &val) {
    133         TreeNode *ptr;
    134         
    135         ptr = m_root;
    136         while (ptr != nullptr) {
    137             if (val < ptr->val) {
    138                 if (ptr->left != nullptr) {
    139                     ptr = ptr->left;
    140                 } else {
    141                     return ptr;
    142                 }
    143             } else if (val > ptr->val) {
    144                 if (ptr->right != nullptr) {
    145                     ptr = ptr->right;
    146                 } else {
    147                     return ptr;
    148                 }
    149             } else {
    150                 return ptr;
    151             }
    152         }
    153         return ptr;
    154     }
    155     
    156     void _preorderTraversalRecursive(const TreeNode  *root, string &result) {
    157         result.push_back('{');
    158         if (root == nullptr) {
    159             // '#' represents NULL.
    160             result.push_back('#');
    161         } else {
    162             result.append(to_string(root->val));
    163             _preorderTraversalRecursive(root->left, result);
    164             _preorderTraversalRecursive(root->right, result);
    165         }
    166         result.push_back('}');
    167     }
    168     
    169     void _inorderTraversalRecursive(const TreeNode  *root, string &result) {
    170         result.push_back('{');
    171         if (root == nullptr) {
    172             // '#' represents NULL.
    173             result.push_back('#');
    174         } else {
    175             _inorderTraversalRecursive(root->left, result);
    176             result.append(to_string(root->val));
    177             _inorderTraversalRecursive(root->right, result);
    178         }
    179         result.push_back('}');
    180     }
    181     
    182     void _postorderTraversalRecursive(const TreeNode  *root, string &result) {
    183         result.push_back('{');
    184         if (root == nullptr) {
    185             // '#' represents NULL.
    186             result.push_back('#');
    187         } else {
    188             _postorderTraversalRecursive(root->left, result);
    189             _postorderTraversalRecursive(root->right, result);
    190             result.append(to_string(root->val));
    191         }
    192         result.push_back('}');
    193     }
    194     
    195     void _shiftLeft(TreeNode *root) {
    196         TreeNode *cur, *par;
    197         
    198         // root and root->left is guaranteed to be non-empty.
    199         par = root;
    200         cur = par->left;
    201         
    202         while (cur->right != nullptr) {
    203             par = cur;
    204             cur = cur->right;
    205         }
    206         root->val = cur->val;
    207         
    208         if (cur->left != nullptr) {
    209             _shiftLeft(cur);
    210             return;
    211         }
    212         
    213         if (cur->right != nullptr) {
    214             _shiftRight(cur);
    215             return;
    216         }
    217         
    218         if (cur->val < par->val) {
    219             delete par->left;
    220             par->left = nullptr;
    221         } else {
    222             delete par->right;
    223             par->right = nullptr;
    224         }
    225     }
    226 
    227     void _shiftRight(TreeNode *root) {
    228         TreeNode *cur, *par;
    229         
    230         // root and root->right is guaranteed to be non-empty.
    231         par = root;
    232         cur = par->right;
    233         
    234         while (cur->left != nullptr) {
    235             par = cur;
    236             cur = cur->left;
    237         }
    238         root->val = cur->val;
    239         
    240         if (cur->left != nullptr) {
    241             _shiftLeft(cur);
    242             return;
    243         }
    244         
    245         if (cur->right != nullptr) {
    246             _shiftRight(cur);
    247             return;
    248         }
    249         
    250         if (cur->val < par->val) {
    251             delete par->left;
    252             par->left = nullptr;
    253         } else {
    254             delete par->right;
    255             par->right = nullptr;
    256         }
    257     }
    258 };
    259 
    260 int main()
    261 {
    262     BinarySearchTree bst;
    263     
    264     bst.insertNode(5);
    265     bst.insertNode(3);
    266     bst.insertNode(14);
    267     bst.insertNode(2);
    268     bst.insertNode(4);
    269     bst.insertNode(9);
    270     bst.insertNode(15);
    271     bst.insertNode(7);
    272     bst.insertNode(8);
    273     cout << bst.preorderTraversal() << endl;
    274     bst.deleteNode(14);
    275     cout << bst.preorderTraversal() << endl;
    276     bst.deleteNode(5);
    277     cout << bst.preorderTraversal() << endl;
    278     
    279     bst.clear();
    280     bst.insertNode(1);
    281     cout << bst.preorderTraversal() << endl;
    282     bst.deleteNode(1);
    283     cout << bst.preorderTraversal() << endl;
    284     
    285     return 0;
    286 }
  • 相关阅读:
    python读取二进制文件写入到txt
    python格式化输出
    字符编码
    python--随时记录
    python-web服务器
    openssh移植
    select、poll、epoll
    (总结)Nginx/LVS/HAProxy负载均衡软件的优缺点详解
    heartbeat与keepalived的区别
    salt 常用命令整理
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3788982.html
Copyright © 2020-2023  润新知