当前位置:   article > 正文

c++数据结构-树(详细总结附代码,一看就懂)_c++树

c++树

树的定义

一棵树是由n(n>0)个元素组成的有限集合,其中:

(1)每个元素称为结点(node)

(2)有一个特定的结点,称为根结点或树根(root)

(3)除根节点外,其余节点能分成m(m>=0)个互不相交的有限集合 T(0)-T(m-1)。其中的每一个子集都是一个树,这些集合被称为这棵树的子树。

如下图是一棵树:

树的基本概念

A. 树是由递归定义的

B. 一棵树中至少有1个结点。这个节点就是根节点,他没有前驱,其余每个节点都有且只有一个前驱节点。每个节点可以有任意个后继结点。因此,树是非线性结构,但也是有序结构。

C. 一个节点的子树个数称为这个结点的度,例如上图根节点的度为2。度为0的结点被称为叶结点;度不为0的结点被称为分支结点,根以外的分支节点称为内部结点,树中各节点的度的最大值称为这棵树的度

D. 在用图形表示的树形结构中,对两个用线段(我们称为树枝)连接的相关联的结点,称上端结点为下端节点的父节点,反之为子节点。

E. 定义一棵树的根的层次为1,其他结点的层次等于他的父节点的层次加一。一棵树中所有节点的层次的最大值称为这棵树的深度

F. 对于树中任意两个不同的结点,从一个结点出发一定能到达另一个结点。

G.m(m>=0)棵树的结合称为森林。

树的遍历

在解决问题时,常常要按照某种次序来获取树中全部节点的信息,这种操作叫做树的遍历。

A. 先序遍历 先访问根节点,然后按照左右先后顺序遍历各子树(根左右)

B. 中序遍历 先访问左子树,然后访问根,最后访问右子树(左根右)

C. 层次遍历 按层次的大笑从小到大遍历,同一层次按照从左到右的顺序。

二叉树基本概念

二叉树(binary tree,简称BT),是一种特殊的树,它的度是2。一个节点有两个子节点,其中左边的是左子节点,右边的是右子节点。左边的叫左子树,右边的叫右子树。

二叉树的性质

(1)在二叉树的第 i 层上最多有 个结点(i>=1)

(2)深度为 k 的二叉树至多有 个结点(k>=1)

特别的,深度为 k ,且有 个结点的二叉树称为满二叉树。

(3)对于任意一棵二叉树,如果其叶子结点数为 ,度为 2 的结点数为 ,那么

(4)具有 n 个结点的完全二叉树的深度为

二叉树的实现

上面我们介绍了树和二叉树,那么我们现在研究一下二叉树的实现,注意,这里默认你有一些 C++ 基础。

首先我们来创建一个二叉树结点类 BSTNode,然后在类中创建几个 BSTNode 类型的变量,值,左子节点,右子节点,父节点。

  1. int _key;
  2. BSTNode *_left; //左子节点
  3. BSTNode *_right; //右子节点
  4. BSTNode *_parent; //父节点

然后我们初始化,这里使用列表初始化。

BSTNode(int k = 0, BSTNode *l = NULL, BSTNode *r = NULL, BSTNode *p = NULL) : _key(k), _left(l), _right(r), _parent(p) {};

接下来,我们来创建一个二叉树类 BinaryTree ,来写二叉树的各种操作函数。

我们先声明函数

  1. void insert(int _key); //将_key节点插入到二叉树中
  2. void PreOrder(); //前序二叉树遍历
  3. void InOrder(); //中序二叉树遍历
  4. void PostOrder(); //后序二叉树遍历
  5. BSTNode *search(int _key); //递归实现,在二叉树中查找_key节点
  6. BSTNode *IteratorSearch(int _key); //迭代实现,在二叉树中查找_key节点
  7. BSTNode *successor(BSTNode *x); //找节点(x)的后继节点。即,查找"二叉树中数据值大于该节点"的"最小节点"
  8. BSTNode *predecessor(BSTNode *x); //找节点(x)的前驱节点。即,查找"二叉树中数据值小于该节点"的"最大节点"
  9. void remove(int _key); //删除_key节点
  10. void destroy(); //销毁二叉树

这里包括了二叉树的基本操作。

类的private部分:

  1. BSTNode *_root; //根节点
  2. void PreOrder(BSTNode *tree); //前序二叉树遍历
  3. void InOrder(BSTNode *tree); //中序二叉树遍历
  4. void PostOrder(BSTNode *tree); //后序二叉树遍历
  5. BSTNode *search(BSTNode *x, int _key); //递归实现,在”二叉树x“中查找_key节点
  6. BSTNode *IteratorSearch(BSTNode *x, int _key); //迭代实现,在“二叉树x”中查找_key节点
  7. BSTNode *minimum(BSTNode *tree); //查找最小节点:返回tree为根节点的二叉树的最小节点
  8. BSTNode *maximum(BSTNode *tree); //查找最大节点:返回tree为根节点的二叉树的最大节点
  9. void insert(BSTNode *&tree, BSTNode *z); // 将节点(z)插入到二叉树(tree)中
  10. BSTNode *remove(BSTNode *tree, BSTNode *z); // 删除二叉树(tree)中的节点(z),并返回被删除的节点
  11. void destroy(BSTNode *&tree); //销毁二叉树

也是声明了一些函数。

插入元素

  1. void BinaryTree::insert(int _key) //将_key节点插入到二叉树中
  2. {
  3. BSTNode *z = new BSTNode(_key, NULL, NULL, NULL);
  4. if (z == NULL)
  5. {
  6. return;
  7. }
  8. insert(_root, z);
  9. }
  1. void BinaryTree::insert(BSTNode *&tree, BSTNode *z) // 将节点(z)插入到二叉树(tree)中
  2. {
  3. BSTNode *y = NULL;
  4. BSTNode *x = tree;
  5. while (x != NULL)
  6. {
  7. y = x;
  8. if (z->_key < x->_key)
  9. {
  10. x = x->_left;
  11. }
  12. else
  13. {
  14. x = x->_right;
  15. }
  16. }
  17. z->_parent = y;
  18. if (y == NULL)
  19. {
  20. tree = z;
  21. }
  22. else
  23. if (z->_key < y->_key)
  24. {
  25. y->_left = z;
  26. }
  27. else
  28. {
  29. y->_right = z;
  30. }
  31. }

首先创建一个结点,如果节点的值(key)是空(NULL)的话就结束函数,如果不为空的话就执行insert函数。insert函数的内容是循环树只要不为空,按照树的顺序找到合适的位置插入元素。

删除结点

  1. BSTNode *BinaryTree::remove(BSTNode *tree, BSTNode *z) // 删除二叉树(tree)中的节点(z),并返回被删除的节点
  2. {
  3. BSTNode *x = NULL;
  4. BSTNode *y = NULL;
  5. if (z->_left == NULL || z->_right == NULL)
  6. {
  7. y = z;
  8. }
  9. else
  10. {
  11. y = successor(z);
  12. }
  13. if (y->_left != NULL)
  14. {
  15. x = y->_left;
  16. }
  17. else
  18. {
  19. x = y->_right;
  20. }
  21. if (x != NULL)
  22. {
  23. x->_parent = y->_parent;
  24. }
  25. if (y->_parent == NULL)
  26. {
  27. tree = x;
  28. }
  29. else
  30. if (y == y->_parent->_left)
  31. {
  32. y->_parent->_left = x;
  33. }
  34. else
  35. {
  36. y->_parent->_right = x;
  37. }
  38. if (y != z)
  39. {
  40. z->_key = y->_key;
  41. }
  42. return y;
  43. }
  1. void BinaryTree::remove(int _key) // 删除二叉树(tree)中的节点(z),并返回被删除的节点
  2. {
  3. BSTNode *z, *node;
  4. z = IteratorSearch(_root, _key);
  5. if (z == _root){
  6. cout<<"Root can't be delete!"<<endl;
  7. }
  8. if (z != NULL && z->_parent != NULL && z != _root)
  9. {
  10. node = remove(_root, z);
  11. if (node != NULL)
  12. {
  13. delete node;
  14. }
  15. }
  16. }

销毁二叉树

  1. void BinaryTree::destroy(BSTNode *&tree) //销毁二叉树
  2. {
  3. if (tree == NULL)
  4. {
  5. return;
  6. }
  7. if (tree->_left != NULL)
  8. {
  9. return destroy(tree->_left);
  10. }
  11. if (tree->_right != NULL)
  12. {
  13. return destroy(tree->_right);
  14. }
  15. delete tree;
  16. tree = NULL;
  17. }
  18. void BinaryTree::destroy() //销毁二叉树
  19. {
  20. destroy(_root);
  21. }

完整代码

  1. /*
  2. 文件创建者: 112233-星澜-imimbert
  3. 创建日期: 2023.1.12 12:33
  4. 功能: 二叉树
  5. */
  6. #include <iostream>
  7. using namespace std;
  8. class BSTNode
  9. {
  10. public:
  11. int _key;
  12. BSTNode *_left; //左子节点
  13. BSTNode *_right; //右子节点
  14. BSTNode *_parent; //父节点
  15. BSTNode(int k = 0, BSTNode *l = NULL, BSTNode *r = NULL, BSTNode *p = NULL) : _key(k), _left(l), _right(r), _parent(p) {}; //初始化列表
  16. };
  17. class BinaryTree
  18. {
  19. /****
  20. * @author 112233-imimbert-星澜
  21. * @since -verson: 1.0.0
  22. * @date 2021-01-12
  23. * @pre 二叉树已经创建
  24. * @include iostream
  25. ****/
  26. public:
  27. BinaryTree();
  28. ~BinaryTree();
  29. void insert(int _key); //将_key节点插入到二叉树中
  30. void PreOrder(); //前序二叉树遍历
  31. void InOrder(); //中序二叉树遍历
  32. void PostOrder(); //后序二叉树遍历
  33. BSTNode *search(int _key); //递归实现,在二叉树中查找_key节点
  34. BSTNode *IteratorSearch(int _key); //迭代实现,在二叉树中查找_key节点
  35. BSTNode *successor(BSTNode *x); //找节点(x)的后继节点。即,查找"二叉树中数据值大于该节点"的"最小节点"
  36. BSTNode *predecessor(BSTNode *x); //找节点(x)的前驱节点。即,查找"二叉树中数据值小于该节点"的"最大节点"
  37. void remove(int _key); //删除_key节点
  38. void destroy(); //销毁二叉树
  39. private:
  40. BSTNode *_root; //根节点
  41. void PreOrder(BSTNode *tree); //前序二叉树遍历
  42. void InOrder(BSTNode *tree); //中序二叉树遍历
  43. void PostOrder(BSTNode *tree); //后序二叉树遍历
  44. BSTNode *search(BSTNode *x, int _key); //递归实现,在”二叉树x“中查找_key节点
  45. BSTNode *IteratorSearch(BSTNode *x, int _key); //迭代实现,在“二叉树x”中查找_key节点
  46. BSTNode *minimum(BSTNode *tree); //查找最小节点:返回tree为根节点的二叉树的最小节点
  47. BSTNode *maximum(BSTNode *tree); //查找最大节点:返回tree为根节点的二叉树的最大节点
  48. void insert(BSTNode *&tree, BSTNode *z); // 将节点(z)插入到二叉树(tree)中
  49. BSTNode *remove(BSTNode *tree, BSTNode *z); // 删除二叉树(tree)中的节点(z),并返回被删除的节点
  50. void destroy(BSTNode *&tree); //销毁二叉树
  51. };
  52. BinaryTree::BinaryTree() :_root(NULL) {};
  53. BinaryTree::~BinaryTree()
  54. {
  55. destroy();
  56. }
  57. void BinaryTree::insert(int _key) //将_key节点插入到二叉树中
  58. {
  59. BSTNode *z = new BSTNode(_key, NULL, NULL, NULL);
  60. if (z == NULL)
  61. {
  62. return;
  63. }
  64. insert(_root, z);
  65. }
  66. void BinaryTree::PreOrder(BSTNode *tree) //前序二叉树遍历
  67. {
  68. if (tree != NULL)
  69. {
  70. cout << tree->_key << " ";
  71. PreOrder(tree->_left);
  72. PreOrder(tree->_right);
  73. }
  74. }
  75. void BinaryTree::PreOrder()
  76. {
  77. PreOrder(_root);
  78. }
  79. void BinaryTree::InOrder(BSTNode *tree) //中序二叉树遍历
  80. {
  81. if (tree != NULL)
  82. {
  83. InOrder(tree->_left);
  84. cout << tree->_key << " ";
  85. InOrder(tree->_right);
  86. }
  87. }
  88. void BinaryTree::InOrder()
  89. {
  90. InOrder(_root);
  91. }
  92. void BinaryTree::PostOrder(BSTNode *tree) //后序二叉树遍历
  93. {
  94. if (tree != NULL)
  95. {
  96. PostOrder(tree->_left);
  97. PostOrder(tree->_right);
  98. cout << tree->_key << " ";
  99. }
  100. }
  101. void BinaryTree::PostOrder()
  102. {
  103. PostOrder(_root);
  104. }
  105. BSTNode *BinaryTree::search(BSTNode *x, int _key) //递归实现,在”二叉树x“中查找_key节点
  106. {
  107. if (x == NULL || _key == x->_key)
  108. {
  109. return x;
  110. }
  111. if (_key < x->_key)
  112. {
  113. return search(x->_left, _key);
  114. }
  115. else
  116. {
  117. return search(x->_right, _key);
  118. }
  119. }
  120. BSTNode *BinaryTree::search(int _key)
  121. {
  122. return search(_root, _key);
  123. }
  124. BSTNode *BinaryTree::IteratorSearch(BSTNode *x, int _key) //迭代实现,在“二叉树x”中查找_key节点
  125. {
  126. while (x != NULL && _key != x->_key)
  127. {
  128. if (_key < x->_key)
  129. {
  130. x = x->_left;
  131. }
  132. else
  133. {
  134. x = x->_right;
  135. }
  136. }
  137. return x;
  138. }
  139. BSTNode *BinaryTree::IteratorSearch(int _key)
  140. {
  141. return IteratorSearch(_root, _key); //传入根节点和待查找的关键字_key
  142. }
  143. BSTNode *BinaryTree::minimum(BSTNode *tree) //查找最小节点:返回tree为根节点的二叉树的最小节点。
  144. {
  145. if (tree == NULL)
  146. {
  147. return NULL;
  148. }
  149. while (tree->_left != NULL)
  150. {
  151. tree = tree->_left;
  152. }
  153. return tree;
  154. }
  155. BSTNode *BinaryTree::maximum(BSTNode *tree) //查找最大节点:返回tree为根节点的二叉树的最大节点。
  156. {
  157. while (tree->_right != NULL)
  158. {
  159. tree = tree->_right;
  160. }
  161. return tree;
  162. }
  163. BSTNode *BinaryTree::successor(BSTNode *x) //找节点(x)的后继节点,也就是该节点的右子树中的最小节点
  164. {
  165. BSTNode *y = NULL;
  166. if (x->_right != NULL)
  167. {
  168. return minimum(x->_right);
  169. }
  170. y = x->_parent;
  171. while (y != NULL && x == y->_right)
  172. {
  173. x = y;
  174. y = y->_parent;
  175. }
  176. return y;
  177. }
  178. BSTNode *BinaryTree::predecessor(BSTNode *x) //找节点(x)的前驱节点是该节点的左子树中的最大节点。
  179. {
  180. BSTNode *y = NULL;
  181. if (x->_left != NULL)
  182. {
  183. return maximum(x->_left);
  184. }
  185. y = x->_parent;
  186. while (y != NULL && x == y->_left)
  187. {
  188. x = y;
  189. y = y->_parent;
  190. }
  191. return y;
  192. }
  193. void BinaryTree::insert(BSTNode *&tree, BSTNode *z) // 将节点(z)插入到二叉树(tree)中
  194. {
  195. BSTNode *y = NULL;
  196. BSTNode *x = tree;
  197. while (x != NULL)
  198. {
  199. y = x;
  200. if (z->_key < x->_key)
  201. {
  202. x = x->_left;
  203. }
  204. else
  205. {
  206. x = x->_right;
  207. }
  208. }
  209. z->_parent = y;
  210. if (y == NULL)
  211. {
  212. tree = z;
  213. }
  214. else
  215. if (z->_key < y->_key)
  216. {
  217. y->_left = z;
  218. }
  219. else
  220. {
  221. y->_right = z;
  222. }
  223. }
  224. BSTNode *BinaryTree::remove(BSTNode *tree, BSTNode *z) // 删除二叉树(tree)中的节点(z),并返回被删除的节点
  225. {
  226. BSTNode *x = NULL;
  227. BSTNode *y = NULL;
  228. if (z->_left == NULL || z->_right == NULL)
  229. {
  230. y = z;
  231. }
  232. else
  233. {
  234. y = successor(z);
  235. }
  236. if (y->_left != NULL)
  237. {
  238. x = y->_left;
  239. }
  240. else
  241. {
  242. x = y->_right;
  243. }
  244. if (x != NULL)
  245. {
  246. x->_parent = y->_parent;
  247. }
  248. if (y->_parent == NULL)
  249. {
  250. tree = x;
  251. }
  252. else
  253. if (y == y->_parent->_left)
  254. {
  255. y->_parent->_left = x;
  256. }
  257. else
  258. {
  259. y->_parent->_right = x;
  260. }
  261. if (y != z)
  262. {
  263. z->_key = y->_key;
  264. }
  265. return y;
  266. }
  267. void BinaryTree::remove(int _key) // 删除二叉树(tree)中的节点(z),并返回被删除的节点
  268. {
  269. BSTNode *z, *node;
  270. z = IteratorSearch(_root, _key);
  271. if (z == _root){
  272. cout<<"Root can't be delete!"<<endl;
  273. }
  274. if (z != NULL && z->_parent != NULL && z != _root)
  275. {
  276. node = remove(_root, z);
  277. if (node != NULL)
  278. {
  279. delete node;
  280. }
  281. }
  282. }
  283. void BinaryTree::destroy(BSTNode *&tree) //销毁二叉树
  284. {
  285. if (tree == NULL)
  286. {
  287. return;
  288. }
  289. if (tree->_left != NULL)
  290. {
  291. return destroy(tree->_left);
  292. }
  293. if (tree->_right != NULL)
  294. {
  295. return destroy(tree->_right);
  296. }
  297. delete tree;
  298. tree = NULL;
  299. }
  300. void BinaryTree::destroy() //销毁二叉树
  301. {
  302. destroy(_root);
  303. }
  304. int main()
  305. {
  306. /************************/
  307. /* 插入
  308. /************************/
  309. BinaryTree *tree = new BinaryTree();
  310. int array[6] = {12, 33, 18, 24, 44, 66};
  311. cout << "二叉树数值:" << endl;
  312. for (int i = 0; i < 6; i++)
  313. {
  314. cout << array[i] << " ";
  315. tree->insert(array[i]); //调用插入函数,生成二叉查找树
  316. }
  317. cout << endl << endl;
  318. /************************/
  319. /* 遍历
  320. /************************/
  321. cout << "前序遍历:";
  322. tree->PreOrder();
  323. cout << endl;
  324. cout << "中序遍历:";
  325. tree->InOrder();
  326. cout << endl;
  327. cout << "后序遍历:";
  328. tree->PostOrder();
  329. cout << endl << endl;
  330. /************************/
  331. /* 查找
  332. /************************/
  333. int _keyword; //查找节点的关键字
  334. cout << "请输入要查找的节点:";
  335. cin >> _keyword;
  336. cout << endl;
  337. BSTNode *node = tree->IteratorSearch(_keyword); //获取数值的地址
  338. if (node) //判断有没有地址
  339. {
  340. cout << "关键字为“" << _keyword << "”的节点,存在。" << endl ;
  341. }
  342. else
  343. {
  344. cout << "关键字为“" << _keyword << "”的节点,不存在。" << endl;
  345. }
  346. cout << endl << endl;
  347. /************************/
  348. /* 删除
  349. /************************/
  350. int DelNode; //要删除的节点
  351. cout << "请输入要删除的节点:";
  352. cin >> DelNode;
  353. tree->remove(DelNode);
  354. cout << endl;
  355. cout << "删除操作后,(前序)遍历:";
  356. tree->PreOrder();
  357. cout << endl;
  358. cout << "删除操作后,(中序)遍历:";
  359. tree->InOrder();
  360. cout << endl;
  361. cout << "删除操作后,(后序)遍历:";
  362. tree->PostOrder();
  363. cout << endl << endl;
  364. /************************/
  365. /* 销毁
  366. /************************/
  367. tree->destroy();
  368. system("pause");
  369. return 0;
  370. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/246271
推荐阅读
相关标签
  

闽ICP备14008679号