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

具体实现代码如下:
- #include "stdafx.h"
- #include <malloc.h>
- #include <stack>
- #include <iostream>
- #define MAXSIZE 100
- using namespace std;
- typedef struct node //二叉树结构体
- {
- int data;
- struct node *lchild;
- struct node *rchild;
- }Bnode,*BTree;
- BTree CreateBinaryTree(BTree &tree){ //创建二叉树
- int inputdata;
- cin >> inputdata;
- if (-1 == inputdata)
- {
- tree = NULL;
- }
- else
- {
- if (!(tree = (Bnode*)malloc(sizeof(Bnode))))
- {
- cout<<"ERROR";
- }
- tree->data = inputdata;
- tree->lchild=CreateBinaryTree(tree->lchild);
- tree->rchild=CreateBinaryTree(tree->rchild);
- }
- return tree;
- }
- void preorderTraverse(BTree tree) //递归前序遍历
- {
- if (tree != NULL)
- {
- cout<<tree->data;
- }
- if (tree->lchild != NULL)
- {
- preorderTraverse(tree->lchild);
- }
- if (tree->rchild)
- {
- preorderTraverse(tree->rchild);
- }
- }
- void preorderTraverse2(BTree tree)
- {
- //////////////////////////////////////////////////////////////////////////
- // 非递归前序
- // 根据前序遍历访问的顺序,优先访问根结点,
- // 然后再分别访问左孩子和右孩子。
- // 即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,
- // 若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,
- // 再访问它的右子树。因此其处理过程如下:
- //
- //////////////////////////////////////////////////////////////////////////
- stack<BTree> s;
- if (!tree)
- {
- cout << "空树" << endl;
- return;
- }
- while (tree || !s.empty())
- {
- while (tree)
- {
- s.push(tree);
- cout << tree->data;
- tree = tree->lchild;
- }
- tree = s.top();
- s.pop();
- tree = tree->rchild;
- }
- }
- void inorderTraverse(BTree tree) //递归中序遍历
- {
- if (tree->lchild)
- {
- inorderTraverse(tree->lchild);
- }
- cout << tree->data;
- if (tree->rchild)
- {
- inorderTraverse(tree->rchild);
- }
- }
- void inorderTraverse2(BTree tree)
- {
- //////////////////////////////////////////////////////////////////////////
- // 非递归中序遍历
- // 根据中序遍历的顺序,对于任一结点,优先访问其左孩子,
- // 而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,
- // 直到遇到左孩子结点为空的结点才进行访问,
- // 然后按相同的规则访问其右子树。
- // 因此其处理过程如下:
- //
- ///////////////////////////////////////////////////////////////////////////
- stack<BTree> s;
- if (!tree)
- {
- cout << "空树" << endl;
- return;
- }
- while (tree || !s.empty())
- {
- while (tree)
- {
- s.push(tree);
- tree = tree->lchild;
- }
- tree = s.top();
- s.pop();
- cout << tree->data;
- tree = tree->rchild;
- }
- }
- void postoderTraverse(BTree tree) //递归后序遍历
- {
- if (tree->lchild)
- {
- postoderTraverse(tree->lchild);
- }
- if (tree->rchild)
- {
- postoderTraverse(tree->rchild);
- }
- cout << tree->data;
- }
- void postoderTraverse2(BTree tree)
- {
- //////////////////////////////////////////////////////////////////////////
- // 非递归后序遍历
- // 要保证根结点在左孩子和右孩子访问之后才能访问,
- // 因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,
- // 则可以直接访问它;或者P存在左孩子或者右孩子,
- // 但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。
- // 若非上述两种情况,则将P的右孩子和左孩子依次入栈,
- // 这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,
- // 左孩子和右孩子都在根结点前面被访问。
- //////////////////////////////////////////////////////////////////////////
- stack<BTree> s;
- BTree cur; //当前结点
- BTree pre = NULL; //前一次访问的结点
- s.push(tree);
- while (!s.empty())
- {
- cur = s.top();
- if ((cur->lchild == NULL&&cur->rchild == NULL) ||(pre != NULL && (pre == cur->lchild || pre == cur->rchild)))
- {
- cout << cur->data; //如果当前结点没有孩子结点或者孩子节点都已被访问过
- s.pop();
- pre = cur;
- }
- else
- {
- if (cur->rchild != NULL)
- s.push(cur->rchild);
- if (cur->lchild != NULL)
- s.push(cur->lchild);
- }
- }
- }
- int Depth(BTree T) //求二叉树的深度
- {
- int dep = 0, depl, depr;
- if (!T) dep = 0;
- else
- {
- depl = Depth(T->lchild);
- depr = Depth(T->rchild);
- dep = 1 + (depl>depr ? depl : depr);
- }
- return dep;
- }
- int sumLeaf(BTree tree) //求叶子节点的个数
- {
- int sum = 0, m, n;
- if (tree)
- {
- if ((!tree->lchild) && (!tree->rchild))
- sum++;
- m = sumLeaf(tree->lchild);
- sum += m;
- n = sumLeaf(tree->rchild);
- sum += n;
- }
- return sum;
- }
- int numnSinglePoint(BTree tree ) //统计度为1的节点数目
- {
- int sum = 0, m, n;
- if (tree)
- {
- if ((tree->lchild!=NULL) && (tree->rchild == NULL))
- sum++;
- if ((tree->lchild == NULL) && (tree->rchild != NULL))
- sum++;
- m = numnSinglePoint(tree->lchild);
- sum += m;
- n = m = numnSinglePoint(tree->rchild);
- sum += n;
- }
- return sum;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- BTree t;
- t= CreateBinaryTree(t);
- cout<<endl<<"非递归前序遍历:";
- preorderTraverse2(t);
- cout << endl<<"----------------------"<<endl;
- cout << "递归前序遍历:";
- preorderTraverse(t);
- cout << endl << "---------------------"<<endl;
- cout << "非递归中序遍历:";
- inorderTraverse2(t);
- cout << endl << "---------------------"<<endl;
- cout << "递归中序遍历:";
- inorderTraverse(t);
- cout << endl << "---------------------"<<endl;
- cout << "非递归后序遍历:";
- postoderTraverse2(t);
- cout << endl << "---------------------"<<endl;
- cout << "递归后序遍历:";
- postoderTraverse(t);
- cout << endl << "----------------------"<<endl;
- cout << "链表深度为:"<<Depth(t);
- cout << endl << "----------------------"<<endl;
- cout << "链表的叶子节点个数为:" << sumLeaf(t);
- cout << endl << "----------------------"<<endl;
- cout << "链表中度为1的节点数目为:" << numnSinglePoint(t) << endl;
- return 0;
- }
构建二叉树示意图为:

运行程序结果为:

c++学习笔记—二叉树基本操作的实现的更多相关文章
- 学习笔记——二叉树相关算法的实现(Java语言版)
二叉树遍历概念和算法 遍历(Traverse): 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问. 从二叉树的递归定义可知,一棵非空的二叉树由根结点及左. ...
- 【Git/GitHub学习笔记】基本操作——创建仓库,本地、远程同步等
近日想分享一些文件,但是用度盘又太麻烦了(速度也很恶心).所以突发奇想去研究了下GitHub的仓库,这篇文章也就是一个最最最基础的基本操作.基本实现了可以在GitHub上存储文本信息与代码. 由于我的 ...
- saltstack学习笔记--grains基本操作
查看当前已经定义的监控项: [root@master ~]# salt "192.168.75.135" grains.items 192.168.75.135: ---- ...
- tensorflow学习笔记三----------基本操作
tensorflow中的一些操作和numpy中的很像,下面列出几个比较常见的操作 import tensorflow as tf #定义三行四列的零矩阵 tf.zeros([3,4]) #定义两行三列 ...
- SQL server2005学习笔记(一)数据库的基本知识、基本操作(分离、脱机、收缩、备份、还原、附加)和基本语法
在软件测试中,数据库是必备知识,假期闲里偷忙,整理了一点学习笔记,共同探讨. 阅读目录 基本知识 数据库发展史 数据库名词 SQL组成 基本操作 登录数据库操作 数据库远程连接操作 数据库分离操作 数 ...
- html5标签video(播放器)学习笔记(二)-基本操作
html5标签video(播放器)学习笔记(二)-基本操作 subying 发布时间: 2014/12/01 23:59 阅读: 13008 收藏: 21 点赞: 3 评论: 0 摘要 本文介绍了ht ...
- Kettle学习笔记(二)— 基本操作
目录 Kettle学习笔记(一)- 环境部署及运行 Kettle学习笔记(二)- 基本操作 kettle学习笔记(三)- 定时任务的脚本执行 Kettle学习笔记(四)- 总结 打开Kettle 打开 ...
- Django 学习笔记(七)数据库基本操作(增查改删)
一.前期准备工作,创建数据库以及数据表,详情点击<Django 学习笔记(六)MySQL配置> 1.创建一个项目 2.创建一个应用 3.更改settings.py 4.更改models.p ...
- 左偏树 / 非旋转treap学习笔记
背景 非旋转treap真的好久没有用过了... 左偏树由于之前学的时候没有写学习笔记, 学得也并不牢固. 所以打算写这么一篇学习笔记, 讲讲左偏树和非旋转treap. 左偏树 定义 左偏树(Lefti ...
随机推荐
- 查看linux系统配置(centos/redhat)
一:查看cpu more /proc/cpuinfo | grep "model name" grep "model name" /proc/cpuinfo 如 ...
- mysql数据库性能测试报告
网上有写的好的模板, 直接复链接了: 1. http://blog.csdn.net/mituan1234567/article/details/45247989 2. https://msdn.mi ...
- EayRadius 于 2013-7-19 进行体验度更新,增加用户体验度
EasyRadius于2013-7-19进行更新,此次更新并没有更新通讯接口,通讯接口将统一更新,包括对其他路由的支持 下面我将主要更新的地方向大家描述一下 如果你有疑问或者建议,可以致电137799 ...
- AJAX简单介绍
什么是AJAX Ajax 是 AsynchronousJavaScript and XML(以及 DHTML 等)的缩写. HTML 用于建立 Web表单并确定应用程序其它部分使用的字段. ·J ...
- .net网站建设页面提交后css失效的问题
问题描述:.net网站建设在提交后出现css部分失效,如div位置,字体大小. 问题解决:原因是,过去的提示语句我们一律使用了Response.write("<script>al ...
- HTML5 FileReader
利用HTML5中的FileReader类,动态切换af中Panel的背景,动态设置img元素的图片 1 if(FileReader){ 2 $('.panel').on("tap" ...
- django时区设置(timezone)
django时区设置(timezone): 默认: TIMEZONE:'America/Chicago'(以前的版本,现在的版本默认的都是UTC时间.) Chicago时间,为UTC/GMT -6 小 ...
- windows下安装node.js
由于shopnc的im需要node.js 先安装下node.js 下载node.js 直接运行 安装完成后 win+R,出入cmd 安装时已经自动配置了环境变量(如果没设置环境变量,变量名:NODE_ ...
- Apache+php5
.下载回来的是解压文件,解压好放到要安装的位置.(我这里以D:\Acpache24为例) .打开Apache24\conf下httpd.conf 文件,用记事本打开即可. ()第37行ServerRo ...
- c# 开发window服务
http://jingyan.baidu.com/article/fa4125acb71a8628ac709226.html 安装 cmd 输入 InstallUtil.exe E:\TestApp\ ...