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. ...
随机推荐
- 9.Palindrome Number (INT)
Determine whether an integer is a palindrome. Do this without extra space. class Solution { public: ...
- react native 触摸Touchable***的区别(TouchableWithoutFeedback、TouchableOpacity、TouchableHighlight、TouchableNativeFeedback)
一.问题背景: react native的跨平台开发没有button的概念,而是使用touchable系列实现点击触发效果. 而touchable系列就有四个之多,而且相互之间仍有较大差别,这就给我们 ...
- [leetcode]134. Gas Station加油站
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. Y ...
- MacOS下打包Python应用
在MacOS下开发的Python应用,不是Web Application,开发好以后,如何给用户使用呢?用户的操作系统也是MacOS 使用py2app打包 一.软件环境 ...
- How To Check Member In Window VS With CplusPlus?
实例说明 下面这个实例代码, 快速举例了在Win32应用程序下,对于内存的泄漏检查. 其中的原理,目前本人还是不太的理解. 只是记录了使用方法. 以后,看情况,会更新的. #ifdef _WIN32 ...
- [Selenium]怎样等待元素出现之后再消失,譬如Loading icon
界面上有些元素是要先等它出现,再等它消失,譬如loading icon 这个是等多个loading icon出现后消失 /** * Wait for loading icon disappear in ...
- [Selenium]怎样验证页面是否有无变化
验证方法:将两次的Dom结构进行对比 String beforeStr = (String) SeleniumUtil.getInnerHTML(page.getDriver(), page.getD ...
- 我们常说的CDN到底是什么?
程序员每天提及的无数词当中,有一个是「CDN」,Ta的中文名是「内容分发网络」,读中文是令人蒙逼的,英文名是Content Delivery Network. CDN有啥用呢?它主要用来解决什么问题呢 ...
- Page Object页面设计模式核心要点
Page Object,页面对象.一种设计模式,实施selenium的最佳实践,体现了web应用与页面显示之间的关系.为什么需要Page Object?测试代码维护的需要:减少代码的编码量,减少代 ...
- Appium之启用手机桌面APP的多种方法
方法一: 其实之前的随笔 Appium之连续启动多个应用(APP)中已经介绍了可以用appium下的start_activity()方法来启动一个应用,那这里就不再说明啦. 方法二: 因为有时用sta ...