当前位置:   article > 正文

二叉树C++实现数据结构实验_binode* bitree::create()//1. 按先序序列构造一棵二叉链表表示

binode* bitree::create()//1. 按先序序列构造一棵二叉链表表示的二叉
  1. #include <iostream>
  2. #include <string.h>
  3. #include <stack>
  4. #include <queue>
  5. using namespace std;
  6. template<class T>
  7. struct BiNode //二叉数节点
  8. {
  9. T data;
  10. BiNode<T>* lchild, *rchild;
  11. };
  12. template<class T> //模板类
  13. class BiTree
  14. {
  15. public:
  16. BiTree(); //默认构造函数
  17. ~BiTree(); //析构函数
  18. BiNode<T>* GetRoot(); //返回根节点
  19. void PreOrder(BiNode<T>* node); //先序遍历
  20. void InOrder(BiNode<T>* node); //中序遍历
  21. void PostOrder(BiNode<T>* node); //后序遍历
  22. void LevelOrder(BiNode<T>* node); //层次遍历
  23. //选做非递归实现
  24. void PreOrderNonRec(BiNode<T>* node); //先
  25. void InOrderNonRec(BiNode<T>* node); //中
  26. void PostOrderNonRec(BiNode<T>* node); //后
  27. //选做深度,节点数,叶子节点数,
  28. int NodesNum(BiNode<T>* node); //节点数
  29. int TreeDepth(BiNode<T>* node); //深度
  30. int LeafNum(BiNode<T>* node); //叶子节点数
  31. //选做交换子树
  32. void SwapChild(BiNode<T>* node); //交换子树
  33. private:
  34. BiNode<T>* m_root; //获取根节点
  35. BiNode<T>* Create(); //创建二叉树
  36. };
  37. template<class T>
  38. BiTree<T>::BiTree()
  39. {
  40. m_root = new BiNode<T>;
  41. m_root = Create();
  42. }
  43. template<class T>
  44. BiTree<T>::~BiTree(){}
  45. template<class T>
  46. BiNode<T>* BiTree<T>::Create() //1. 按先序序列构造一棵二叉链表表示的二叉树T;
  47. {
  48. char ch=getchar();
  49. BiNode<T>* pnode;
  50. if (ch == ' ')
  51. pnode = NULL;
  52. else
  53. {
  54. pnode = new BiNode<T>;
  55. pnode->data = ch;
  56. pnode->lchild = Create();
  57. pnode->rchild = Create();
  58. }
  59. return pnode;
  60. }
  61. template<class T>
  62. BiNode<T>* BiTree<T>::GetRoot()
  63. {
  64. return m_root;
  65. }
  66. template<class T>
  67. void BiTree<T>::PreOrder(BiNode<T>* node)
  68. {
  69. if (!node)
  70. return;
  71. else
  72. {
  73. cout << node->data;
  74. PreOrder(node->lchild);
  75. PreOrder(node->rchild);
  76. }
  77. }
  78. template<class T>
  79. void BiTree<T>::InOrder(BiNode<T>* node)
  80. {
  81. //前后定根,中序定左右
  82. if (!node)
  83. return;
  84. else
  85. {
  86. InOrder(node->lchild);
  87. cout << node->data;
  88. InOrder(node->rchild);
  89. }
  90. }
  91. template<class T>
  92. void BiTree<T>::PostOrder(BiNode<T>* node)
  93. {
  94. if (!node)
  95. return;
  96. else
  97. {
  98. PostOrder(node->lchild);
  99. PostOrder(node->rchild);
  100. cout << node->data;
  101. }
  102. }
  103. template<class T>
  104. void BiTree<T>::LevelOrder(BiNode<T>* node)
  105. {
  106. //层次遍历需要queue来实现,思路:
  107. //@1初始化queue
  108. // if root为空 返回
  109. //@2 push(root)
  110. //@3 while(queue不为空)
  111. // s <-- queue.front()
  112. // queue.pop()
  113. // 输入s.data
  114. // if(s的左子树不空)
  115. // s的左子树入队
  116. // if(s的右子树不空)
  117. // s的右子树入队
  118. queue<BiNode<T>*> q;
  119. BiNode<T>* s = node;
  120. if (!s)
  121. return;
  122. q.push(s);
  123. while (!q.empty())
  124. {
  125. s = q.front();
  126. q.pop();
  127. cout << s->data;
  128. if (s->lchild)
  129. q.push(s->lchild);
  130. if (s->rchild)
  131. q.push(s->rchild);
  132. }
  133. }
  134. //先序遍历非递归需要借助stack s来实现,模拟递归调用
  135. //总的循环边界是当前节点不为空或者stack不空,
  136. template<class T>
  137. void BiTree<T>::PreOrderNonRec(BiNode<T>* node)
  138. {
  139. stack<BiNode<T>*> s;
  140. BiNode<T>* p = node;
  141. while (p|| !s.empty())
  142. {
  143. /*
  144. @1.每次找当前的节点的左子节点直到左为空,经过的节点入栈,
  145. @2.然后弹出当前节点,搜索一次右节点,如果p为空并且s空则退出否则继续@1
  146. */
  147. while (p)//这里执行VL
  148. {
  149. cout << p->data;//V
  150. s.push(p);//访问过的加入栈
  151. p = p->lchild;//L
  152. }
  153. if (!s.empty())//这里执行R
  154. {
  155. p = s.top();
  156. s.pop();
  157. p = p->rchild;//R
  158. }
  159. }
  160. }
  161. template<class T>
  162. void BiTree<T>::InOrderNonRec(BiNode<T>* node)
  163. {
  164. //@1 在当前节点p非空时候,将p入栈s,p的左子树赋给p,保证左子树都能入栈
  165. // p为空时候,也就是左子树最左边访问到了,这时候在栈非空的时候
  166. //@2 取栈顶给p,输入p,出栈,这时候最底层的最左边节点访问了,将p的右子树赋给p,重复@1
  167. stack<BiNode<T>*> s;
  168. BiNode<T>* p = node;
  169. while (p|| !s.empty())
  170. {
  171. while (p)//这里执行L
  172. {
  173. s.push(p);
  174. p = p->lchild;
  175. }
  176. if (!s.empty())//这里执行VR
  177. {
  178. p = s.top();
  179. cout << p->data;
  180. s.pop();
  181. p = p->rchild;
  182. }
  183. }
  184. }
  185. template<class T>
  186. void BiTree<T>::PostOrderNonRec(BiNode<T>* node)
  187. {
  188. //访问子节点的条件有两种
  189. //1.当前节点的左右节点都为空,可以直接访问
  190. //2.前一个被访问的节点是当前节点的子节点
  191. //这样就需要两个指针,一个指向当前一个指向前一个被访问的节点
  192. //然后保证入栈顺序是先右再左,(这里先压右再压左,这样左在上面,就先访问左)
  193. if (!node)
  194. return;
  195. stack<BiNode<T>*> s;
  196. s.push(node);
  197. BiNode<T>* pre = NULL;
  198. BiNode<T>* cur;
  199. while (!s.empty())
  200. {
  201. cur = s.top();
  202. if (!cur->lchild&& !cur->rchild ||(pre != NULL) && (pre == cur->lchild || pre == cur->rchild))//上一次访问的是当前节点的左子树
  203. {
  204. cout << cur->data;
  205. s.pop();
  206. pre = cur;//pre是前一个被访问的节点
  207. }
  208. else
  209. {
  210. if (cur->rchild)
  211. s.push(cur->rchild);
  212. if (cur->lchild)
  213. s.push(cur->lchild);
  214. }
  215. }
  216. }
  217. template<class T>
  218. int BiTree<T>::LeafNum(BiNode<T>* node)
  219. {
  220. //递归思路:找到叶子节点返回值加一,返回值计数
  221. //2种情况
  222. //1.节点为空,返回 0,传递回去
  223. //2.每当到达叶子节点,返回 1,传递给上一层函数
  224. if (!node)
  225. return 0;
  226. if (!node->lchild&&!node->rchild)
  227. return 1;
  228. return LeafNum(node->lchild) + LeafNum(node->rchild);
  229. }
  230. template<class T>
  231. int BiTree<T>::TreeDepth(BiNode<T>* node)
  232. {
  233. /*
  234. 递归思路:
  235. 每个节点都有自己的左右子树,
  236. 每次返回当前节点左右子树长度大的那个
  237. 1.如果根节点为空,则深度为0,返回0,递归的出口
  238. 2.否则深度至少为1,然后累加他们左右子树的深度,
  239. */
  240. int LChildDep = 1, RChildDep = 1;
  241. if (!node)
  242. return 0;
  243. LChildDep += TreeDepth(node->lchild);//每次返回之前子树的长度
  244. RChildDep += TreeDepth(node->rchild);
  245. return (LChildDep>RChildDep) ? (LChildDep) : (RChildDep);
  246. }
  247. template<class T>
  248. int BiTree<T>::NodesNum(BiNode<T>* node)
  249. {
  250. //思路,递归遍历所有节点,如果不是空节点的话,递归返回值加1
  251. if (!node)
  252. return 0;
  253. return NodesNum(node->lchild) + NodesNum(node->rchild) + 1;
  254. }
  255. template<class T>
  256. void BiTree<T>::SwapChild(BiNode<T>* node)
  257. {
  258. //思路,交换所有节点的节点,每个节点走一遍
  259. if (node)
  260. {
  261. swap(node->lchild, node->rchild);
  262. SwapChild(node->lchild);
  263. SwapChild(node->rchild);
  264. }
  265. }
  266. /*
  267. 样例输入:
  268. ABC DE G F ↙
  269. 样例输出:
  270. 先序建立一棵二叉树,请输入节点的值:ABC DE G F
  271. 建立完毕.
  272. 先序:ABCDEGF
  273. 中序:CBEGDFA
  274. 后序:CGEFDBA
  275. 层序:ABCDEFG
  276. 选做题1:采用非递归算法实现二叉树遍历
  277. 先序:ABCDEGF
  278. 中序:CBEGDFA
  279. 后序:CGEFDBA
  280. 选做题2:求二叉树的深度/结点数目/叶结点数目
  281. TreeDepth is 5
  282. NodesNum is 7
  283. LeafNum is 3
  284. 选做题3:将二叉树每个结点的左右子树交换位置。
  285. 交换完毕.
  286. 先序:ABDFEGC
  287. 中序:AFDGEBC
  288. 后序:FGEDCBA
  289. 层序:ABDCFEG
  290. */
  291. int main()
  292. {
  293. cout << "先序建立一棵二叉树,请输入节点的值:";
  294. BiTree<char> bitree;
  295. cout << "建立完毕." << endl;
  296. cout << "先序:";
  297. bitree.PreOrder(bitree.GetRoot());
  298. cout << endl;
  299. cout << "中序:";
  300. bitree.InOrder(bitree.GetRoot());
  301. cout << endl;
  302. cout << "后序:";
  303. bitree.PostOrder(bitree.GetRoot());
  304. cout << endl;
  305. cout << "层序:";
  306. bitree.LevelOrder(bitree.GetRoot());
  307. cout << endl;
  308. cout << "选做题1:采用非递归算法实现二叉树遍历" << endl;
  309. cout << "先序:";
  310. bitree.PreOrderNonRec(bitree.GetRoot());
  311. cout << endl;
  312. cout << "中序:";
  313. bitree.InOrderNonRec(bitree.GetRoot());
  314. cout << endl;
  315. cout << "后序:";
  316. bitree.PostOrderNonRec(bitree.GetRoot());
  317. cout << endl;
  318. cout << "选做题2:求二叉树的深度/结点数目/叶结点数目" << endl;
  319. cout << "深度为 : " << bitree.TreeDepth(bitree.GetRoot()) << endl;
  320. cout << "结点数目 : " << bitree.NodesNum(bitree.GetRoot()) << endl;
  321. cout << "叶结点数目: " << bitree.LeafNum(bitree.GetRoot()) << endl;
  322. cout << "选做题3:将二叉树每个结点的左右子树交换位置。" << endl;
  323. bitree.SwapChild(bitree.GetRoot());
  324. cout << "交换完毕." << endl;
  325. cout << "先序:";
  326. bitree.PreOrder(bitree.GetRoot());
  327. cout << endl;
  328. cout << "中序:";
  329. bitree.InOrder(bitree.GetRoot());
  330. cout << endl;
  331. cout << "后序:";
  332. bitree.PostOrder(bitree.GetRoot());
  333. cout << endl;
  334. cout << "层序:";
  335. bitree.LevelOrder(bitree.GetRoot());
  336. cout << endl;
  337. system("pause");
  338. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号