二叉树的二叉链表存储表示如下

//二叉树的二叉链表存储表示
typedef struct BiTNode {
char data;//结点数据域
struct BiTNode* lchild, * rchild;//左右孩子指针
}*BiTree;

根据括号表示法的字符串创建树(括号里的表示括号前结点的子结点,‘,’号左边是左子结点,右边是右子结点)

比如:a(b(d,e),c(f,g(h,i)))

表示的则是

//创建树
void CreateBiTree(BiTree& T)
{
stack<BiTNode*> s;//用于确定需要操作的结点
BiTNode* p=NULL;
int i = 0;
bool child_Direct;//0表示左子结点,1表示右子结点
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
string TreeStr;
cin >> TreeStr;
while (TreeStr[i] != '\0') {
switch (TreeStr[i])
{
case'('://左子结点
s.push(p);
child_Direct = false;
break;
case')':
s.pop();
case','://右子结点
child_Direct = true;
break; default:
p = new BiTNode;
p->data = TreeStr[i];
p->lchild = p->rchild = NULL;
if (T == NULL)//若根节点为空则p指向根节点
T = p;
else {
if (!child_Direct)
s.top()->lchild = p;
else
s.top()->rchild = p;
}
break;
}
i++;
} }

  

非递归先序、中序、后序遍历

先序:

void PreOrderTraverse(BiTree T) {
stack<BiTNode*> s;
BiTNode* p = T, * q = new BiTNode();
while (p != NULL || !s.empty()) {
if (p)//p非空
{
cout << p->data;
s.push(p);//根指针入栈
p = p->lchild;//遍历左子树
}
else {
p = s.top();
s.pop();
p = p->rchild;//遍历右子树
}
}
}

  

中序:

//中序遍历
void InOrderTraverse(BiTree T) {
stack<BiTNode*> s;
BiTNode* p = T, * q = new BiTNode();
while (p != NULL || !s.empty()) {
if (p)//p非空
{
s.push(p);//根指针入栈
p = p->lchild;//遍历左子树
}
else {
p = s.top();
s.pop();
cout << p->data;
p = p->rchild;//遍历右子树
}
}
}

  

后序:

//后序遍历
void PostOrderTraverse(BiTree T) {
BiTNode* p = T, * r = NULL;
stack<BiTNode*> s;
while (p != NULL || !s.empty()) {
if (p != NULL) {//走到最左边
s.push(p);
p = p->lchild;
}
else {
p = s.top();
if (p->rchild != NULL && p->rchild != r)//右子树存在,未被访问
p = p->rchild;
else {
s.pop();
cout << p->data;
r = p;//记录最近访问过的节点
p = NULL;//节点访问完后,重置p指针
}
}//else
}//while }

完整代码

#include <iostream>
#include <stack>
#include <string>
using namespace std; //二叉树的二叉链表存储表示
typedef struct BiTNode {
char data;//结点数据域
struct BiTNode* lchild, * rchild;//左右孩子指针
}*BiTree; void Initial(BiTree& T) {
T = new BiTNode;
T = NULL;
}
//创建树
void CreateBiTree(BiTree& T)
{
stack<BiTNode*> s;//用于确定需要操作的结点
BiTNode* p=NULL;
int i = 0;
bool child_Direct;//0表示左子结点,1表示右子结点
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
string TreeStr;
cin >> TreeStr;
while (TreeStr[i] != '\0') {
switch (TreeStr[i])
{
case'('://左子结点
s.push(p);
child_Direct = false;
break;
case')':
s.pop();
case','://右子结点
child_Direct = true;
break; default:
p = new BiTNode;
p->data = TreeStr[i];
p->lchild = p->rchild = NULL;
if (T == NULL)//若根节点为空则p指向根节点
T = p;
else {
if (!child_Direct)
s.top()->lchild = p;
else
s.top()->rchild = p;
}
break;
}
i++;
} }
//以括号表示法输出二叉树
void DispBTNode(BiTNode *&b)
{
if (b != NULL)
{
cout<<b->data;
if (b->lchild != NULL || b->rchild != NULL)
{
cout<<"(";
DispBTNode(b->lchild);
if (b->rchild != NULL) cout<<(",");
DispBTNode(b->rchild);
cout<<")";
}
}
} #pragma region 递归遍历
//先序
void PreOrderTraverseR(BiTree T) {
if (T != NULL) {
cout << T->data;
PreOrderTraverseR(T->lchild);
PreOrderTraverseR(T->rchild);
}
}
//中序
void InOrderTraverseR(BiTree T) {
if (T != NULL) {
InOrderTraverseR(T->lchild);
cout << T->data;
InOrderTraverseR(T->rchild);
}
}
//后序
void PostOrderTraverseR(BiTree T) {
if (T != NULL) {
PostOrderTraverseR(T->lchild);
PostOrderTraverseR(T->rchild);
cout << T->data;
}
}
#pragma endregion #pragma region 非递归遍历
//先序遍历
void PreOrderTraverse(BiTree T) {
stack<BiTNode*> s;
BiTNode* p = T, * q = new BiTNode();
while (p != NULL || !s.empty()) {
if (p)//p非空
{
cout << p->data;
s.push(p);//根指针入栈
p = p->lchild;//遍历左子树
}
else {
p = s.top();
s.pop();
p = p->rchild;//遍历右子树
}
}
}
//中序遍历
void InOrderTraverse(BiTree T) {
stack<BiTNode*> s;
BiTNode* p = T, * q = new BiTNode();
while (p != NULL || !s.empty()) {
if (p)//p非空
{
s.push(p);//根指针入栈
p = p->lchild;//遍历左子树
}
else {
p = s.top();
s.pop();
cout << p->data;
p = p->rchild;//遍历右子树
}
}
}
//后序遍历
void PostOrderTraverse(BiTree T) {
BiTNode* p = T, * r = NULL;
stack<BiTNode*> s;
while (p != NULL || !s.empty()) {
if (p != NULL) {//走到最左边
s.push(p);
p = p->lchild;
}
else {
p = s.top();
if (p->rchild != NULL && p->rchild != r)//右子树存在,未被访问
p = p->rchild;
else {
s.pop();
cout << p->data;
r = p;//记录最近访问过的节点
p = NULL;//节点访问完后,重置p指针
}
}//else
}//while }
#pragma endregion
int main()
{
BiTree b;
Initial(b);
//创建树
CreateBiTree(b);
//先序遍历
cout << "先序遍历:";
PreOrderTraverse(b);
cout << endl;
//中序遍历
cout << "中序遍历:";
InOrderTraverse(b);
cout << endl;
//后序遍历
cout << "后序遍历:";
PostOrderTraverse(b);
}

  

程序示例:

C++学习---二叉树的输入及非递归遍历的更多相关文章

  1. 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java

    前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...

  2. C++编程练习(17)----“二叉树非递归遍历的实现“

    二叉树的非递归遍历 最近看书上说道要掌握二叉树遍历的6种编写方式,之前只用递归方式编写过,这次就用非递归方式编写试一试. C++编程练习(8)----“二叉树的建立以及二叉树的三种遍历方式“(前序遍历 ...

  3. ZT 二叉树的非递归遍历

    ZT 二叉树的非递归遍历 二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就 是递归定 ...

  4. c语言描述的二叉树的基本操作(层序遍历,递归,非递归遍历)

    #include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define ...

  5. 数据结构之二叉树篇卷三 -- 二叉树非递归遍历(With Java)

    Nonrecursive Traversal of Binary Tree First I wanna talk about why we should <code>Stack</c ...

  6. [Alg] 二叉树的非递归遍历

    1. 非递归遍历二叉树算法 (使用stack) 以非递归方式对二叉树进行遍历的算法需要借助一个栈来存放访问过得节点. (1) 前序遍历 从整棵树的根节点开始,对于任意节点V,访问节点V并将节点V入栈, ...

  7. 二叉树3种递归和非递归遍历(Java)

    import java.util.Stack; //二叉树3种递归和非递归遍历(Java) public class Traverse { /******************一二进制树的定义*** ...

  8. c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)

    二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: ...

  9. JAVA递归、非递归遍历二叉树(转)

    原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { priva ...

随机推荐

  1. python变量及简单数据类型

    python 目录 python 1.变量 1.变量的定义 2.变量的命名 3. 关键字 4.变量的命名规则 5.变量的类型 5.不同类型变量之间的计算 6.变量的输入 7.变量的格式化输出 8.格式 ...

  2. day52:django:ORM单表/多表操作

    目录 1.ORM 2.ORM单表增删改查 13个必知必会的查询接口 filter基于双下划线的模糊查询 3.ORM多表增删改查 ORM 什么是ORM? ORM(object relational ma ...

  3. 设计模式 | Catalog设计模式,抵御业务方需求变动

    大家好,这是一个全新的专题--设计模式. 其实可以选择的专题还有好几个,为什么选择设计模式呢?原因也很简单,首先是设计模式简单.易学.干货的文章固然好,但是普适性往往不强.另外一个很重要的点就是设计模 ...

  4. k8s运行容器之deployment(三)

    deployment 我们已经知道k8s是通过各种controller来管理pod的生命周期.为了满足不同业务场景,k8s开发了Deployment.ReplicaSet.DaemonSet.Stat ...

  5. ABP VNext从单体切换到微服务

    注:此处的微服务只考虑服务部分,不考虑内外层网关.认证等. ABP VNext从单体切换到微服务,提供了相当大的便利性,对于各模块内部不要做任何调整,仅需要调整承载体即可. ABP can help ...

  6. XSS平台简单使用

    XSS常用语句及编码绕过 XSS常用的测试语句有: <script>alert(1)</script> <img src=x onerror=alert(1)> & ...

  7. 基础Web漏洞-SQL注入入门(手工注入篇)

    一.什么是SQL注入  SQL是操作数据库数据的结构化查询语言,网页的应用数据和后台数据库中的数据进行交互时会采用SQL.而SQL注入是将Web页面的原URL.表单域或数据包输入的参数,修改拼接成SQ ...

  8. mysql 空值(null)和空字符('')的区别

    日常开发中,一般都会涉及到数据库增删改查,那么不可避免会遇到Mysql中的NULL和空字符. 空字符(")和空值(null)表面上看都是空,其实存在一些差异: 定义: 空值(NULL)的长度 ...

  9. Ubuntu部署和体验Nexus3

    关于Nexus 如下图,在局域网部署了Nexus之后,可以缓存中央仓库的jar,开发者开发的二方库发布到Nexus上,局域网内的其他人也可以从Nexus下载这些二方库使用: 环境信息 本次实战是在Li ...

  10. jq显示数据在kindeditor

    1,定义编辑器的变量为全局变量 2,将数据显示到kindeditor   在我自己这里_下划线相当于数据,也就是将数据显示在kindeditor 中的textarea中 3,jquery获取kinde ...