用c++语言实现的二叉树基本操作,包括二叉树的创建、二叉树的遍历(包括前序、中序、后序递归和非递归算法)、求二叉树高度,计数叶子节点数、计数度为1的节点数等基本操作。

IDE:vs2013

具体实现代码如下:

  1. #include "stdafx.h"
  2. #include <malloc.h>
  3. #include <stack>
  4. #include <iostream>
  5. #define MAXSIZE 100
  6. using namespace std;
  7. typedef struct node   //二叉树结构体
  8. {
  9. int data;
  10. struct node *lchild;
  11. struct node *rchild;
  12. }Bnode,*BTree;
  13. BTree CreateBinaryTree(BTree &tree){            //创建二叉树
  14. int inputdata;
  15. cin >> inputdata;
  16. if (-1 == inputdata)
  17. {
  18. tree = NULL;
  19. }
  20. else
  21. {
  22. if (!(tree = (Bnode*)malloc(sizeof(Bnode))))
  23. {
  24. cout<<"ERROR";
  25. }
  26. tree->data = inputdata;
  27. tree->lchild=CreateBinaryTree(tree->lchild);
  28. tree->rchild=CreateBinaryTree(tree->rchild);
  29. }
  30. return tree;
  31. }
  32. void preorderTraverse(BTree tree)    //递归前序遍历
  33. {
  34. if (tree != NULL)
  35. {
  36. cout<<tree->data;
  37. }
  38. if (tree->lchild != NULL)
  39. {
  40. preorderTraverse(tree->lchild);
  41. }
  42. if (tree->rchild)
  43. {
  44. preorderTraverse(tree->rchild);
  45. }
  46. }
  47. void preorderTraverse2(BTree tree)
  48. {
  49. //////////////////////////////////////////////////////////////////////////
  50. //          非递归前序
  51. //    根据前序遍历访问的顺序,优先访问根结点,
  52. //    然后再分别访问左孩子和右孩子。
  53. //    即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,
  54. //    若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,
  55. //    再访问它的右子树。因此其处理过程如下:
  56. //
  57. //////////////////////////////////////////////////////////////////////////
  58. stack<BTree> s;
  59. if (!tree)
  60. {
  61. cout << "空树" << endl;
  62. return;
  63. }
  64. while (tree || !s.empty())
  65. {
  66. while (tree)
  67. {
  68. s.push(tree);
  69. cout << tree->data;
  70. tree = tree->lchild;
  71. }
  72. tree = s.top();
  73. s.pop();
  74. tree = tree->rchild;
  75. }
  76. }
  77. void inorderTraverse(BTree tree)      //递归中序遍历
  78. {
  79. if (tree->lchild)
  80. {
  81. inorderTraverse(tree->lchild);
  82. }
  83. cout << tree->data;
  84. if (tree->rchild)
  85. {
  86. inorderTraverse(tree->rchild);
  87. }
  88. }
  89. void inorderTraverse2(BTree tree)
  90. {
  91. //////////////////////////////////////////////////////////////////////////
  92. //            非递归中序遍历
  93. //      根据中序遍历的顺序,对于任一结点,优先访问其左孩子,
  94. //      而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,
  95. //       直到遇到左孩子结点为空的结点才进行访问,
  96. //       然后按相同的规则访问其右子树。
  97. //       因此其处理过程如下:
  98. //
  99. ///////////////////////////////////////////////////////////////////////////
  100. stack<BTree> s;
  101. if (!tree)
  102. {
  103. cout << "空树" << endl;
  104. return;
  105. }
  106. while (tree || !s.empty())
  107. {
  108. while (tree)
  109. {
  110. s.push(tree);
  111. tree = tree->lchild;
  112. }
  113. tree = s.top();
  114. s.pop();
  115. cout << tree->data;
  116. tree = tree->rchild;
  117. }
  118. }
  119. void postoderTraverse(BTree tree)     //递归后序遍历
  120. {
  121. if (tree->lchild)
  122. {
  123. postoderTraverse(tree->lchild);
  124. }
  125. if (tree->rchild)
  126. {
  127. postoderTraverse(tree->rchild);
  128. }
  129. cout << tree->data;
  130. }
  131. void postoderTraverse2(BTree tree)
  132. {
  133. //////////////////////////////////////////////////////////////////////////
  134. //          非递归后序遍历
  135. //      要保证根结点在左孩子和右孩子访问之后才能访问,
  136. //  因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,
  137. //  则可以直接访问它;或者P存在左孩子或者右孩子,
  138. //  但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。
  139. //  若非上述两种情况,则将P的右孩子和左孩子依次入栈,
  140. //  这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,
  141. //  左孩子和右孩子都在根结点前面被访问。
  142. //////////////////////////////////////////////////////////////////////////
  143. stack<BTree> s;
  144. BTree cur;                        //当前结点
  145. BTree pre = NULL;                 //前一次访问的结点
  146. s.push(tree);
  147. while (!s.empty())
  148. {
  149. cur = s.top();
  150. if ((cur->lchild == NULL&&cur->rchild == NULL) ||(pre != NULL && (pre == cur->lchild || pre == cur->rchild)))
  151. {
  152. cout << cur->data;  //如果当前结点没有孩子结点或者孩子节点都已被访问过
  153. s.pop();
  154. pre = cur;
  155. }
  156. else
  157. {
  158. if (cur->rchild != NULL)
  159. s.push(cur->rchild);
  160. if (cur->lchild != NULL)
  161. s.push(cur->lchild);
  162. }
  163. }
  164. }
  165. int Depth(BTree T)   //求二叉树的深度
  166. {
  167. int dep = 0, depl, depr;
  168. if (!T) dep = 0;
  169. else
  170. {
  171. depl = Depth(T->lchild);
  172. depr = Depth(T->rchild);
  173. dep = 1 + (depl>depr ? depl : depr);
  174. }
  175. return dep;
  176. }
  177. int sumLeaf(BTree tree)   //求叶子节点的个数
  178. {
  179. int sum = 0, m, n;
  180. if (tree)
  181. {
  182. if ((!tree->lchild) && (!tree->rchild))
  183. sum++;
  184. m = sumLeaf(tree->lchild);
  185. sum += m;
  186. n = sumLeaf(tree->rchild);
  187. sum += n;
  188. }
  189. return sum;
  190. }
  191. int numnSinglePoint(BTree tree )    //统计度为1的节点数目
  192. {
  193. int sum = 0, m, n;
  194. if (tree)
  195. {
  196. if ((tree->lchild!=NULL) && (tree->rchild == NULL))
  197. sum++;
  198. if ((tree->lchild == NULL) && (tree->rchild != NULL))
  199. sum++;
  200. m = numnSinglePoint(tree->lchild);
  201. sum += m;
  202. n = m = numnSinglePoint(tree->rchild);
  203. sum += n;
  204. }
  205. return sum;
  206. }
  207. int _tmain(int argc, _TCHAR* argv[])
  208. {
  209. BTree t;
  210. t= CreateBinaryTree(t);
  211. cout<<endl<<"非递归前序遍历:";
  212. preorderTraverse2(t);
  213. cout << endl<<"----------------------"<<endl;
  214. cout << "递归前序遍历:";
  215. preorderTraverse(t);
  216. cout << endl << "---------------------"<<endl;
  217. cout << "非递归中序遍历:";
  218. inorderTraverse2(t);
  219. cout << endl << "---------------------"<<endl;
  220. cout << "递归中序遍历:";
  221. inorderTraverse(t);
  222. cout << endl << "---------------------"<<endl;
  223. cout << "非递归后序遍历:";
  224. postoderTraverse2(t);
  225. cout << endl << "---------------------"<<endl;
  226. cout << "递归后序遍历:";
  227. postoderTraverse(t);
  228. cout << endl << "----------------------"<<endl;
  229. cout << "链表深度为:"<<Depth(t);
  230. cout << endl << "----------------------"<<endl;
  231. cout << "链表的叶子节点个数为:" << sumLeaf(t);
  232. cout << endl << "----------------------"<<endl;
  233. cout << "链表中度为1的节点数目为:" << numnSinglePoint(t) << endl;
  234. return 0;
  235. }

构建二叉树示意图为:

运行程序结果为:

c++学习笔记—二叉树基本操作的实现的更多相关文章

  1. 学习笔记——二叉树相关算法的实现(Java语言版)

    二叉树遍历概念和算法 遍历(Traverse): 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问. 从二叉树的递归定义可知,一棵非空的二叉树由根结点及左. ...

  2. 【Git/GitHub学习笔记】基本操作——创建仓库,本地、远程同步等

    近日想分享一些文件,但是用度盘又太麻烦了(速度也很恶心).所以突发奇想去研究了下GitHub的仓库,这篇文章也就是一个最最最基础的基本操作.基本实现了可以在GitHub上存储文本信息与代码. 由于我的 ...

  3. saltstack学习笔记--grains基本操作

    查看当前已经定义的监控项: [root@master ~]# salt "192.168.75.135" grains.items 192.168.75.135:     ---- ...

  4. tensorflow学习笔记三----------基本操作

    tensorflow中的一些操作和numpy中的很像,下面列出几个比较常见的操作 import tensorflow as tf #定义三行四列的零矩阵 tf.zeros([3,4]) #定义两行三列 ...

  5. SQL server2005学习笔记(一)数据库的基本知识、基本操作(分离、脱机、收缩、备份、还原、附加)和基本语法

    在软件测试中,数据库是必备知识,假期闲里偷忙,整理了一点学习笔记,共同探讨. 阅读目录 基本知识 数据库发展史 数据库名词 SQL组成 基本操作 登录数据库操作 数据库远程连接操作 数据库分离操作 数 ...

  6. html5标签video(播放器)学习笔记(二)-基本操作

    html5标签video(播放器)学习笔记(二)-基本操作 subying 发布时间: 2014/12/01 23:59 阅读: 13008 收藏: 21 点赞: 3 评论: 0 摘要 本文介绍了ht ...

  7. Kettle学习笔记(二)— 基本操作

    目录 Kettle学习笔记(一)- 环境部署及运行 Kettle学习笔记(二)- 基本操作 kettle学习笔记(三)- 定时任务的脚本执行 Kettle学习笔记(四)- 总结 打开Kettle 打开 ...

  8. Django 学习笔记(七)数据库基本操作(增查改删)

    一.前期准备工作,创建数据库以及数据表,详情点击<Django 学习笔记(六)MySQL配置> 1.创建一个项目 2.创建一个应用 3.更改settings.py 4.更改models.p ...

  9. 左偏树 / 非旋转treap学习笔记

    背景 非旋转treap真的好久没有用过了... 左偏树由于之前学的时候没有写学习笔记, 学得也并不牢固. 所以打算写这么一篇学习笔记, 讲讲左偏树和非旋转treap. 左偏树 定义 左偏树(Lefti ...

随机推荐

  1. Android 耳机插入过程分析 (AudioManager部分)

    接上一篇,记录audioManager对耳机插入的操作 https://www.cnblogs.com/helloworldtoyou/p/9868890.html 主要是发送广播,另外更新音频通路 ...

  2. 建议大家使用Java 8 的日期、时间,而非java.util.Date

    建议大家使用Java 8 的日期.时间,而非java.util.Date. 详细原因见:如何在Java 8中愉快地处理日期和时间 总结一下就是, java.util.Date 太乱,如 月份从0开始. ...

  3. e613. Modifying the Focus Traversal Order

    JFrame frame = new JFrame(); JButton component1 = new JButton("1"); JButton component2 = n ...

  4. JAVA组成原理及使用方法编辑环境及实现过程

    JAVA组成原理一.由四方面组成:1.Java编程语言2.Java类文件格式3.Java虚拟机4.Java应用程序接口 当编辑并运行一个Java程序时,需要同时涉及到这四种方面.二.使用文字编辑软件: ...

  5. 浅谈android中只使用一个TextView实现高仿京东,淘宝各种倒计时

    今天给大家带来的是只使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.近期公司一直加班也没来得及时间去整理,今天难得歇息想把这个分享给大家.只求共同学习,以及自己兴许 ...

  6. Lemon OA第1篇:简单介绍

    官方网站:http://www.mossle.com/ 声明:我不是Lemon OA作者,只是分享好的资源.以下内容均代表个人见解~ 从官网说起 知道Lemon OA,也是最近研究Activiti,看 ...

  7. 简明Linux命令行笔记:touch

    创建文件或修改文件时间 touch [options] file-list 参数 file-list是touch将要创建或更新的文件路径名 选项 -a                    只更新访问 ...

  8. hive以文件创建表

    create table location( location string, ip string, name string, city string, classfication string, c ...

  9. 一键切换hosts文件

    1.新建文件host.bat 2.代码 @echo off cd.>C:\Windows\System32\drivers\etc\hosts echo .本地环境 .线上测试环境 ,切换Hos ...

  10. XToDo未完成内容标记管理器

    下载地址:https://github.com/trawor/XToDo 跟VVDocumenter规范注释生成器的安装方式一样: 下载开源工程在Xcode重新编译运行会自动安装此插件,重启Xcode ...