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 ...
随机推荐
- SAP 物料移动类型查询表
Goods movement w/o referenceB Goods movement for purchase orderF Goods movement for production order ...
- BitSet 是个好东西
顾名思义,就是位集合(bit set),是从JDK 1.0就出现的东西,后面的版本又慢慢强化. 我们说学习一样东西,最好是场景驱动 - 要考虑它的使用场景,这样才有意义. 那么,BitSet的应用场景 ...
- 服务不支持chkconfig的解决
场景: 写了脚本,想用命令chkconfig加载自启动. chkconfig mongod on 解决方法: mongod 脚本的开头要这样加: #!/bin/bash #chkconfig:345 ...
- Maven初步踩坑
2015-02-08 今天创建maven项目,要从中央仓库下载一堆包到本地仓库,等了好久.结果下好了之后,maven项目上有个感叹号,也没有发现代码里哪配置有错误. 和实验室好多小伙伴一起交流 也没找 ...
- 【Intel AF 2.1 学习笔记二】AF中的页面——Panel
Panel Panel控件是你的app中的独立内容的区域控件.它是af UI的核心.Panel div 元素实际上承载了app中你管理和显示的界面元素和内容. 创建panel控件是相当地容易的:在id ...
- 文件传输协议(FTP,SFTP,SCP)(修改中)
FTP(File Transfer Protocol):是TCP/IP网络上两台计算机传送文件的协议,FTP是在TCP/IP网络和INTERNET上最早使用的协议之一,它属于网络协议组的应用层.FTP ...
- ZooKeeper ACL权限设置
ZK的节点有5种操作权限:CREATE.READ.WRITE.DELETE.ADMIN 也就是 增.删.改.查.管理权限,这5种权限简写为crwda(即:每个单词的首字符缩写)注:这5种权限中,del ...
- VSCode升级后启动不了~
之前安装了VSCode,一直用的好好的,每次启动后后下角总会提示自己有新版本可以更新,然后就手贱点击了更新,然后就出问题了,更新后VSCode无法启动,打不开了,哭死! 于是,我尝试了以下方法,均无济 ...
- 深入理解css3中的flex-grow、flex-shrink、flex-basis
https://www.cnblogs.com/ghfjj/p/6529733.html
- docker 相关文章
https://baijiahao.baidu.com/s?id=1581420975184566963&wfr=spider&for=pc 创建centos基础镜像 https ...