• 波奇学C++:抽象类和搜索二叉树


    抽象类:接口类,不能实例化类,派生类必须重写函数才能使用。

    1. class Car
    2. {
    3. public:
    4. //纯虚函数
    5. virtual void Drive() = 0;
    6. };
    1. class Benz :public Car
    2. {
    3. public:
    4. virtual void Drive()
    5. {
    6. cout << "Benz" << endl;
    7. }
    8. };

    Benz重写后才能实例化,本质上抽象类是为了强制重写

    静态成员函数不能是虚函数,没有this指针,不能通过虚表调用

    构造函数不能是虚函数,虚表是在编译时生成,虚表在初始化列表才有,调用构造函数,会在虚表生成前,析构函数是虚函数。

    虚函数调用慢于普通函数和内联函数。

    虚函数表在编译阶段生成,存在代码端

    菱形继承是数据冗余和二义性。

    搜索二叉树:BST 

    左节点<根节点<右节点

    1. template<class K>
    2. struct BSTreeNode
    3. {
    4. BSTreeNode* _left;
    5. BSTreeNode* _right;
    6. K _key;
    7. BSTreeNode(const K& key)
    8. :_left(nullptr)
    9. ,_right(nullptr)
    10. ,_key(key)
    11. {
    12. }
    13. };
    14. template<class K>
    15. class BSTree
    16. {
    17. typedef BSTreeNode Node;
    18. public:
    19. BSTree()
    20. :_root(nullptr)
    21. {
    22. }
    23. bool Insert(const K& key)
    24. {
    25. if (_root == nullptr)
    26. {
    27. _root = new Node(key);
    28. return true;
    29. }
    30. Node* parent = nullptr;
    31. Node* cur = _root;
    32. while (cur)
    33. {
    34. if (cur->_key < key)
    35. {
    36. parent = cur;
    37. cur = cur->_right;
    38. }
    39. else if (cur->_key > key)
    40. {
    41. parent = cur;
    42. cur = cur->_left;
    43. }
    44. else
    45. {
    46. return false;
    47. }
    48. }
    49. cur = new Node(key);
    50. if (parent->_key < key)
    51. {
    52. parent->_right = cur;
    53. }
    54. else
    55. {
    56. parent->_left = cur;
    57. }
    58. return true;
    59. }
    60. bool Find(const K& key)
    61. {
    62. Node* cur = _root;
    63. while (cur)
    64. {
    65. if (cur->_key < key)
    66. {
    67. cur = cur->_right;
    68. }
    69. else if (cur->_key > key)
    70. {
    71. cur = cur->_left;
    72. }
    73. return false;
    74. }
    75. }
    76. bool Erase(const K& key)
    77. {
    78. Node* parent = nullptr;
    79. Node* cur = _root;
    80. while (cur)
    81. {
    82. if (cur->_key < key)
    83. {
    84. parent = cur;
    85. cur = cur->_right;
    86. }
    87. else if (cur->_key > key)
    88. {
    89. parent = cur;
    90. cur = cur->_left;
    91. }
    92. else //找到了
    93. {
    94. // 左为空
    95. if (cur->_left ==nullptr)
    96. {
    97. if (cur == _root)
    98. {
    99. _root = cur->_right;
    100. }
    101. else
    102. {
    103. if (parent->_right == cur)
    104. {
    105. parent->_right = cur->_right;
    106. }
    107. else
    108. {
    109. parent->_left = cur->_right;
    110. }
    111. }
    112. }
    113. // 右为空
    114. else if (cur->_right == nullptr)
    115. {
    116. if (cur == _root)
    117. {
    118. _root = cur->_left;
    119. }
    120. else{
    121. if (parent->_right == cur)
    122. {
    123. parent->_right = cur->_left;
    124. }
    125. else
    126. {
    127. parent->_left = cur->_left;
    128. }
    129. }
    130. }
    131. else
    132. {
    133. Node* parent = cur;
    134. Node* leftMax = cur->_left;
    135. while (leftMax->_right)
    136. {
    137. parent = leftMax;
    138. leftMax = leftMax->_right;
    139. }
    140. swap(cur->_key, leftMax->_key);
    141. if (parent->_left == leftMax)
    142. {
    143. parent->_left = leftMax->_left;
    144. }
    145. else
    146. {
    147. parent->_right = leftMax->_left;
    148. }
    149. cur = leftMax;
    150. }
    151. delete cur;
    152. return true;
    153. }
    154. }
    155. return false;
    156. }
    157. void InOrder()
    158. {
    159. _InOrder(_root);
    160. }
    161. void _InOrder(Node* root)
    162. {
    163. if (root == NULL)
    164. {
    165. return;
    166. }
    167. _InOrder(root->_left);
    168. std::cout << root->_key << " ";
    169. _InOrder(root->_right);
    170. }
    171. private:
    172. Node* _root;
    173. };
    174. void TestBSTree1()
    175. {
    176. int a[] = { 8,3,1,10,6,4,7,14,13 };
    177. BSTree<int> t;
    178. for (auto e : a)
    179. {
    180. t.Insert(e);
    181. }
    182. t.InOrder();
    183. t.Erase(6);
    184. printf("\n");
    185. t.InOrder();
    186. }

    搜索二叉树递归版

    1. #include
    2. using namespace std;
    3. template<typename T>
    4. struct BSTreeNode
    5. {
    6. // 引用是为了value对像是自定义结构体,防止深拷贝
    7. BSTreeNode(const T& value)
    8. :_left(nullptr)
    9. ,_right(nullptr)
    10. ,_value(value)
    11. {
    12. }
    13. BSTreeNode* _left;
    14. BSTreeNode* _right;
    15. T _value;
    16. };
    17. template<typename T>
    18. class BSTree
    19. {
    20. typedef BSTreeNode Node;
    21. public:
    22. BSTree()
    23. :root(nullptr)
    24. {
    25. }
    26. BSTree(const BSTree& s)
    27. {
    28. root=Copy(root,s.root);
    29. }
    30. ~BSTree()
    31. {
    32. Destory(root);
    33. }
    34. bool Insert(const T& value)
    35. {
    36. if (root == nullptr)
    37. {
    38. root = new Node(value);
    39. return true;
    40. }
    41. Node* cur = root;
    42. Node* before = root;
    43. while (cur)
    44. {
    45. if (value>cur->_value)
    46. {
    47. before = cur;
    48. cur = cur->_right;
    49. }
    50. else if (value < cur->_value)
    51. {
    52. before = cur;
    53. cur = cur->_left;
    54. }
    55. else
    56. {
    57. return false;
    58. }
    59. }
    60. //找到空的位置,区分是在左还是右
    61. // 比较值也可以
    62. if (before->_right)
    63. {
    64. // 左为空
    65. before->_left = new Node(value);
    66. }
    67. else if (before->_left)
    68. {
    69. // 右为空,左不为空
    70. before->_right = new Node(value);
    71. }
    72. else
    73. {
    74. // 左右都为空
    75. if (value > before->_value)
    76. {
    77. // 放在右边
    78. before->_right = new Node(value);
    79. }
    80. else
    81. {
    82. before->_left = new Node(value);
    83. }
    84. }
    85. return true;
    86. }
    87. bool InsertR(const T& value)
    88. {
    89. return _InsertR(root, value);
    90. }
    91. bool FindR(const T& value)
    92. {
    93. return _FindR(root, value);
    94. }
    95. bool Find(const T& value)
    96. {
    97. Node* cur = root;
    98. while(cur)
    99. {
    100. if (value < cur->_value)
    101. {
    102. cur = cur->_left;
    103. }
    104. else if (value>cur->_value)
    105. {
    106. cur=cur->_right;
    107. }
    108. else
    109. {
    110. return true;
    111. }
    112. }
    113. return false;
    114. }
    115. bool EraseR(const T& value)
    116. {
    117. return _EraseR(root, value);
    118. }
    119. bool Erase(const T& value)
    120. {
    121. Node* before = root;
    122. Node* cur = root;
    123. while (cur)
    124. {
    125. if (cur->_value < value)
    126. {
    127. before = cur;
    128. cur = cur->_right;
    129. }
    130. else if (cur->_value > value)
    131. {
    132. before = cur;
    133. cur = cur->_left;
    134. }
    135. else
    136. {
    137. // 分为左右为空
    138. if (!cur->_left && !cur->_right)
    139. {
    140. // 判断节点是左还是右
    141. //节点为左
    142. if (before->_left==cur)
    143. {
    144. before->_left = nullptr;
    145. }
    146. else
    147. {
    148. before->_right = nullptr;
    149. }
    150. }
    151. // 分为左为空,右不为空
    152. else if (!cur->_left&&cur->_right)
    153. {
    154. Node* next = cur->_right;
    155. if (before->_left == cur)
    156. {
    157. before->_left = next;
    158. }
    159. else
    160. {
    161. before->_right = next;
    162. }
    163. }
    164. // 右为空,左不为空
    165. else if(cur->_left&&!cur->_right)
    166. {
    167. Node* next = cur->_left;
    168. if (before->_left == cur)
    169. {
    170. before->_left = next;
    171. }
    172. else
    173. {
    174. before->_right = next;
    175. }
    176. }
    177. else
    178. {
    179. //两边非空都,找左树的最大值右或者右树的最大值
    180. Node* pos = cur;
    181. Node* left_max = cur->_left;
    182. while(left_max->_right)
    183. {
    184. cur = left_max;
    185. left_max = left_max->_right;
    186. }
    187. swap(left_max->_value, pos->_value);
    188. //第一个左节点构成左树
    189. if (cur->_left == left_max)
    190. {
    191. cur->_left = left_max->_left;
    192. }
    193. else
    194. {
    195. cur->_right = left_max->_left;
    196. }
    197. // 把cur强行定义为要释放的值
    198. cur = left_max;
    199. }
    200. delete cur;
    201. return true;
    202. }
    203. }
    204. return false;
    205. }
    206. void InOrder()
    207. {
    208. _InOrder(root);
    209. printf("\n");
    210. }
    211. private:
    212. // 递归返回
    213. Node* Copy(Node* root,Node* root1)
    214. {
    215. if (root1 == nullptr)
    216. {
    217. return nullptr;
    218. }
    219. root = new Node(root1->_value);
    220. root->_left = Copy(root,root1->_left);
    221. root->_right = Copy(root,root1->_right);
    222. return root;
    223. }
    224. // 递归释放空间
    225. void Destory(Node* root)
    226. {
    227. if (root == nullptr)
    228. {
    229. return;
    230. }
    231. Destory(root->_left);
    232. Destory(root->_right);
    233. delete root;
    234. return;
    235. }
    236. bool _EraseR(Node*& root, const T& value)
    237. {
    238. if (root == nullptr)
    239. {
    240. return false;
    241. }
    242. if (value >root->_value)
    243. {
    244. return _EraseR(root->_right, value);
    245. }
    246. else if (value < root->_value)
    247. {
    248. return _EraseR(root->_left, value);
    249. }
    250. else
    251. {
    252. Node* leftmax = root->_left;
    253. if (leftmax == nullptr)
    254. {
    255. Node* del = root;
    256. root = nullptr;
    257. delete del;
    258. return true;
    259. }
    260. while (leftmax->_right)
    261. {
    262. leftmax = leftmax->_right;
    263. }
    264. swap(root->_value, leftmax->_value);
    265. // 只取左树依然是符号树的规律
    266. return _EraseR(root->_left, value);
    267. }
    268. }
    269. bool _InsertR(Node*& root, const T& value)
    270. {
    271. if (root == nullptr)
    272. {//传引用使得可以直接赋值
    273. // 当要修改某个节点,且这个操作不是递归操作
    274. root = new Node(value);
    275. return true;
    276. }
    277. if (value < root->_value)
    278. {
    279. return _InsertR(root->_left, value);
    280. }
    281. else if(root->_value
    282. {
    283. return _InsertR(root->_right,value);
    284. }
    285. else
    286. {
    287. return false;
    288. }
    289. }
    290. bool _FindR(Node* root, const T& value)
    291. {
    292. if (root == nullptr)
    293. {
    294. return false;
    295. }
    296. if (value < root->_value)
    297. {
    298. return _FindR(root->_left, value);
    299. }
    300. else if(value>root->_value)
    301. {
    302. return _FindR(root->_right, value);
    303. }
    304. else
    305. {
    306. return true;
    307. }
    308. }
    309. void _InOrder(Node* root)
    310. {
    311. if (root == nullptr)
    312. {
    313. return;
    314. }
    315. _InOrder(root->_left);
    316. cout << root->_value;
    317. _InOrder(root->_right);
    318. }
    319. Node* root;
    320. };

  • 相关阅读:
    Zabbix技术分享——使用docker-compose快速部署zabbix监控系统
    【C++入门系列】——命名空间和输入输出
    基于Minifilter框架的双缓冲透明加解密驱动 课程论文+项目源码
    使用Redis查询数据库数据增加访问速度小案例
    Java数组
    Spring Cloud AWS配置中心使用
    [异构图-论文阅读]Heterogeneous Graph Transformer
    mac电脑版数字图像处理软件:ACDSee Photo Studio 9最新 for Mac
    MySQL学习笔记-----Navicat设置建表
    springcloud-01-注册中心
  • 原文地址:https://blog.csdn.net/Bagayalu1234567/article/details/132826741