C++实现二叉树的相应操作
1. 二叉树的遍历:先序(递归、非递归),中序(递归、非递归),后序(递归、非递归)。
#include <iostream>
#include <string>
#include <stack> using namespace std; struct BiTree
{
int NodeData = ;
struct BiTree *pLeft = nullptr;
struct BiTree *pRight = nullptr;
}; //遍历二叉树:
void show(struct BiTree *pRoot, int n)
{
if (pRoot == nullptr)
{
return;
}
else
{
show(pRoot->pLeft, n + ); for (int i = ; i < n; i++)
cout << " ";
cout << pRoot->NodeData << endl; show(pRoot->pRight, n + );
} }
//--------------------------------------------------------------
//递归中序遍历:
void RecMidTravel(struct BiTree *pRoot)
{
if (pRoot == nullptr)
{
return;
}
else
{
if (pRoot->pLeft != nullptr)
{
RecMidTravel(pRoot->pLeft);
} cout << pRoot->NodeData << endl; if (pRoot->pRight != nullptr)
{
RecMidTravel(pRoot->pRight);
}
}
} //中序非递归
void MidTravel(struct BiTree *pRoot)
{
if (pRoot == nullptr)
{
return;
}
else
{ struct BiTree *pcur = pRoot;
stack<BiTree *> mystack; while (!mystack.empty() || pcur != nullptr)
{
while (pcur != nullptr)
{
mystack.push(pcur);
pcur = pcur->pLeft; //左节点全部进栈
} if (!mystack.empty())
{
pcur = mystack.top();
cout << pcur->NodeData << endl;
mystack.pop(); //出栈
pcur = pcur->pRight; //右节点
}
} }
}
//--------------------------------------------------------------
//递归先序遍历:
void RecPreTravel(struct BiTree *pRoot)
{
if (pRoot == nullptr)
{
return;
}
else
{
cout << pRoot->NodeData << endl; if (pRoot->pLeft != nullptr)
{
RecPreTravel(pRoot->pLeft);
} if (pRoot->pRight != nullptr)
{
RecPreTravel(pRoot->pRight);
}
}
}
//先序非递归
void PreTravel(struct BiTree *pRoot)
{
if (pRoot == nullptr)
{
return;
}
else
{ struct BiTree *pcur = pRoot;
stack<BiTree *> mystack; while (!mystack.empty() || pcur != nullptr)
{
while (pcur != nullptr)
{
cout << pcur->NodeData << endl; mystack.push(pcur);
pcur = pcur->pLeft; //左节点全部进栈
} if (!mystack.empty())
{
pcur = mystack.top(); mystack.pop(); //出栈
pcur = pcur->pRight; //右节点
}
} }
} //--------------------------------------------------------------
//递归后序遍历:
void RecPostTravel(struct BiTree *pRoot)
{
if (pRoot == nullptr)
{
return;
}
else
{
if (pRoot->pLeft != nullptr)
{
RecPostTravel(pRoot->pLeft);
} if (pRoot->pRight != nullptr)
{
RecPostTravel(pRoot->pRight);
} cout << pRoot->NodeData << endl;
}
}
//后序非递归
struct nosame //标识节点是否反复出现
{
struct BiTree *pnode;
bool issame;
}; void PostTravel(struct BiTree *pRoot)
{
if (pRoot == nullptr)
{
return;
}
else
{ struct BiTree *pcur = pRoot;
stack<nosame *> mystack; //避免重复出现
nosame *ptemp; while (!mystack.empty() || pcur != nullptr)
{
while (pcur != nullptr)
{
nosame *ptr = new nosame;
ptr->issame = true;
ptr->pnode = pcur;//节点 //cout << pcur->NodeData << endl; mystack.push(ptr);
pcur = pcur->pLeft; //左节点全部进栈
} if (!mystack.empty())
{
ptemp = mystack.top();
mystack.pop(); //出栈 if (ptemp->issame == true) //第一次出现
{
ptemp->issame = false;
mystack.push(ptemp);
pcur = ptemp->pnode->pRight;//跳到右节点
}
else
{
cout << ptemp->pnode->NodeData << endl;//打印数据
pcur = nullptr;
} }
} }
} void main()
{
struct BiTree *pRoot; struct BiTree node1;
struct BiTree node2;
struct BiTree node3;
struct BiTree node4;
struct BiTree node5;
struct BiTree node6;
struct BiTree node7;
struct BiTree node8; node1.NodeData = ;
node2.NodeData = ;
node3.NodeData = ;
node4.NodeData = ;
node5.NodeData = ;
node6.NodeData = ;
node7.NodeData = ;
node8.NodeData = ; pRoot = &node1;
node1.pLeft = &node2;
node1.pRight = &node3; node2.pLeft = &node4;
node2.pRight = &node5; node3.pLeft = &node6;
node3.pRight = &node7; node4.pLeft = &node8; show(pRoot, ); cout << "中序递归:" << endl;
RecMidTravel(pRoot); //中序递归
cout << "中序非递归:" << endl;
MidTravel(pRoot); //中序非递归 cout << "先序递归:" << endl;
RecPreTravel(pRoot);
cout << "先序非递归:" << endl;
PreTravel(pRoot); //先序非递归 cout << "后序递归:" << endl;
RecPostTravel(pRoot);
cout << "后序非递归:" << endl;
PostTravel(pRoot); //后序非递归 cin.get();
}
2. 获取二叉树节点个数:
//递归获取二叉树节点个数
int getNodeCount(BiTree *pRoot)
{
if (pRoot == nullptr)
{
return ;
}
else
{
return getNodeCount(pRoot->pLeft) + getNodeCount(pRoot->pRight) + ;
}
}
3. 判断二叉树是否为完全二叉树:
//判断二叉树是否为完全二叉树
bool isCompleteBiTree(BiTree *pRoot)
{
if (pRoot == nullptr)
{
return false;
}
else
{
queue<BiTree *> myq;
myq.push(pRoot);
bool mustHaveChild = false; //必须有子节点
bool result = true; //结果 while (!myq.empty())
{
BiTree *node = myq.front();//头结点
myq.pop(); //出队 if (mustHaveChild) //必须有孩子
{
if (node->pLeft != nullptr || node->pRight != nullptr)
{
result = false;
break; } }
else
{
if (node->pLeft != nullptr && node->pRight != nullptr)
{
myq.push(node->pLeft);
myq.push(node->pRight);
}
else if (node->pLeft != nullptr && node->pRight == nullptr)
{
mustHaveChild = true;
myq.push(node->pLeft);
}
else if (node->pLeft == nullptr && node->pRight != nullptr)
{
result = false;
break;
}
else
{
mustHaveChild = true;
}
}
} return result;
}
}
4. 求二叉树两个节点的最小公共祖先:
//求二叉树两个节点的最小公共祖先
bool findnode(BiTree *pRoot, BiTree *node) //判断节点是否在某个节点下
{
if (pRoot == nullptr || node == nullptr)
{
return false;
}
if (pRoot == node)
{
return true;
} bool isfind = findnode(pRoot->pLeft, node);
if (!isfind)
{
isfind = findnode(pRoot->pRight, node);
} return isfind;
} BiTree *getParent(BiTree *pRoot, BiTree *pChild1, BiTree *pChild2)
{
if (pRoot == pChild1 || pRoot == pChild2)
{
return pRoot;
} if (findnode(pRoot->pLeft, pChild1))
{
if (findnode(pRoot->pRight, pChild2))
{
return pRoot;
}
else
{
return getParent(pRoot->pLeft, pChild1, pChild2);
}
}
else
{
if (findnode(pRoot->pLeft, pChild2))
{
return pRoot;
}
else
{
return getParent(pRoot->pRight, pChild1, pChild2);
}
}
}
5. 二叉树的翻转:
//二叉树的翻转
BiTree *revBiTree(BiTree *pRoot)
{
if (pRoot==nullptr)
{
return nullptr;
} BiTree *leftp = revBiTree(pRoot->pLeft);
BiTree *rightp = revBiTree(pRoot->pRight); pRoot->pLeft = rightp;
pRoot->pRight = leftp; //交换 return pRoot;
}
6. 求二叉树第k层的节点个数:
//求二叉树第K层的节点个数
int getLevelConut(BiTree *pRoot, int k)
{
if (pRoot == nullptr || k < )
{
return ;
}
if (k == )
{
return ;
}
else
{
int left = getLevelConut(pRoot->pLeft, k - );
int right = getLevelConut(pRoot->pRight, k - ); return (left + right);
}
}
7. 求二叉树中节点的最大距离(相距最远的两个节点之间的距离):
//求二叉树中节点的最大距离
struct res //用以递归间传递距离
{
int maxDistance = ;
int maxDepth = ;
}; res getMaxDistance(BiTree *pRoot)
{
if (pRoot == nullptr)
{
res r1;
return r1;
} res leftr = getMaxDistance(pRoot->pLeft);
res rightr = getMaxDistance(pRoot->pRight); res last; //最终结果
last.maxDepth = max(leftr.maxDepth + , rightr.maxDepth + );//求最大深度
last.maxDistance = max(max(leftr.maxDistance, rightr.maxDistance), leftr.maxDepth + rightr.maxDepth + );//求最大距离 return last;
}
8. 判断二叉树是否为平衡二叉树:
//判断二叉树是否为平衡二叉树:
bool isAVL(BiTree *pRoot, int & depth) //需要引用来传递数据
{
if (pRoot == nullptr)
{
depth = ;
return true;
} int leftdepth = ;
int rightdepth = ;
bool left = isAVL(pRoot->pLeft, leftdepth);
bool right = isAVL(pRoot->pRight, rightdepth); if (left && right && abs(leftdepth - rightdepth) <= )
{
depth = + (leftdepth > rightdepth ? leftdepth : rightdepth);//深度
return true;
}
else
{
return false;
}
}
C++实现二叉树的相应操作的更多相关文章
- 二叉树的简单操作(Binary Tree)
树形结构应该是贯穿整个数据结构的一个比较重要的一种结构,它的重要性不言而喻! 讲到树!一般都是讨论二叉树,而关于二叉树的定义以及概念这里不做陈诉,可自行搜索. 在C语言里面需要实现一个二叉树,我们需要 ...
- 二叉树各种相关操作(建立二叉树、前序、中序、后序、求二叉树的深度、查找二叉树节点,层次遍历二叉树等)(C语言版)
将二叉树相关的操作集中在一个实例里,有助于理解有关二叉树的相关操作: 1.定义树的结构体: typedef struct TreeNode{ int data; struct TreeNode *le ...
- c++排序二叉树的出现的私有函数讨论,以及二叉树的删除操作详解
c++排序二叉树的出现的私有函数讨论, 以及二叉树的删除操作详解 标签(空格分隔): c++ 前言 我在c++学习的过程中, 最近打了一个排序二叉树的题目,题目中出现了私有函数成员,当时没有理解清楚这 ...
- Java 二叉树遍历相关操作
BST二叉搜索树节点定义: /** * BST树的节点类型 * @param <T> */ class BSTNode<T extends Comparable<T>&g ...
- java实现二叉树的相关操作
import java.util.ArrayDeque; import java.util.Queue; public class CreateTree { /** * @param args */ ...
- 二叉树JAVA实现
为了克服对树结构编程的畏惧感和神秘感,下定决心将二叉树的大部分操作实现一遍,并希望能够掌握二叉树编程的一些常用技术和技巧.关于编程实现中的心得和总结,敬请期待!~ [1] 数据结构和表示: 二叉树的 ...
- 【数据结构】之二叉树的java实现
转自:http://blog.csdn.net/wuwenxiang91322/article/details/12231657 二叉树的定义: 二叉树是树形结构的一个重要类型.许多实际问题抽象出来的 ...
- [STL源码剖析]RB-tree的插入操作
RB-tree的性质 对于RB-tree,首先做一个了解,先看一张维基百科的RB-tree: 再看RB-tree的性质: 性质1. 节点是红色或黑色. 性质2. 根是黑色,所有叶子都是黑色(叶子节点指 ...
- C实现二叉树(模块化集成,遍历的递归与非递归实现)
C实现二叉树模块化集成 实验源码介绍(源代码的总体介绍):header.h : 头文件链栈,循环队列,二叉树的结构声明和相关函数的声明.LinkStack.c : 链栈的相关操作函数定义.Queue. ...
随机推荐
- S导入部门数据 更新父部门、责任人
导入部门数据分两步骤,EXCEL模板可以一样 一.导入部门主数据,导入时选择INSERT (注意以下还有问题,父区域会自动带出一个值) [Public] ConnectString=host=&quo ...
- ios7 导航栏适配
ios ui开发过程中,经常会使用到导航栏,默认的样式比较单一,所以经常需要修改导航栏的样式 ios4: - (void)drawRect:(CGRect)rect { UIImage *image ...
- Visual studio 2017编译 boost
下载: https://www.boost.org/ 或者 https://dl.bintray.com/boostorg/release/1.66.0/source/ 下载完成以后解压到自己想要 ...
- [z]hadoop生态系统
http://developer.51cto.com/art/201311/415639_all.htm
- Laravel 引入自定义类库或第三方类库
强烈建议引入的类 都是含有命名空间的,这样使用起来就不会出现重名的情况.!!当然,没有命名空间也可以使用,就是类名字(非文件名)最好复杂一些.(重复也不要紧,程序会自己判断) laravel5.4中如 ...
- [Selenium]Turn Page By Scroll Bar
Description: Need to turn page by operating scroll bar and find out the element in the current page. ...
- HBase 系列(三)HBase Shell
HBase 系列(三)HBase Shell ./hbase shell # 进入 hbase 命令行 (1) HBase 命令帮助 help # 查看 HBase 所有的命令 create # 或 ...
- 前端福利之jQuery文字轮播特效(转)
闲谈:离开学校那座象牙塔已经也有大半年的事件了,生活中不再充满了茫然只有忙碌.连续加班加点大半个月,做的活动项目终于算是告一段落了,而今天也将是考验其真正价值的时候,现在将这次开发中遇到的问题做一下总 ...
- canvas里调用getImageData的报security的问题
canvas元素支持绘制任意图片元素: var ctx = document.getElementById("canvas").getContext("2d") ...
- 企业搜索引擎开发之连接器connector(十八)
创建并启动连接器实例之后,连接器就会基于Http协议向指定的数据接收服务器发送xmlfeed格式数据,我们可以通过配置http代理服务器抓取当前基于http协议格式的数据(或者也可以通过其他网络抓包工 ...