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 ...
随机推荐
- Android 耳机插入过程分析 (AudioManager部分)
接上一篇,记录audioManager对耳机插入的操作 https://www.cnblogs.com/helloworldtoyou/p/9868890.html 主要是发送广播,另外更新音频通路 ...
- 建议大家使用Java 8 的日期、时间,而非java.util.Date
建议大家使用Java 8 的日期.时间,而非java.util.Date. 详细原因见:如何在Java 8中愉快地处理日期和时间 总结一下就是, java.util.Date 太乱,如 月份从0开始. ...
- e613. Modifying the Focus Traversal Order
JFrame frame = new JFrame(); JButton component1 = new JButton("1"); JButton component2 = n ...
- JAVA组成原理及使用方法编辑环境及实现过程
JAVA组成原理一.由四方面组成:1.Java编程语言2.Java类文件格式3.Java虚拟机4.Java应用程序接口 当编辑并运行一个Java程序时,需要同时涉及到这四种方面.二.使用文字编辑软件: ...
- 浅谈android中只使用一个TextView实现高仿京东,淘宝各种倒计时
今天给大家带来的是只使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.近期公司一直加班也没来得及时间去整理,今天难得歇息想把这个分享给大家.只求共同学习,以及自己兴许 ...
- Lemon OA第1篇:简单介绍
官方网站:http://www.mossle.com/ 声明:我不是Lemon OA作者,只是分享好的资源.以下内容均代表个人见解~ 从官网说起 知道Lemon OA,也是最近研究Activiti,看 ...
- 简明Linux命令行笔记:touch
创建文件或修改文件时间 touch [options] file-list 参数 file-list是touch将要创建或更新的文件路径名 选项 -a 只更新访问 ...
- hive以文件创建表
create table location( location string, ip string, name string, city string, classfication string, c ...
- 一键切换hosts文件
1.新建文件host.bat 2.代码 @echo off cd.>C:\Windows\System32\drivers\etc\hosts echo .本地环境 .线上测试环境 ,切换Hos ...
- XToDo未完成内容标记管理器
下载地址:https://github.com/trawor/XToDo 跟VVDocumenter规范注释生成器的安装方式一样: 下载开源工程在Xcode重新编译运行会自动安装此插件,重启Xcode ...