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++实现二叉树的相应操作的更多相关文章

  1. 二叉树的简单操作(Binary Tree)

    树形结构应该是贯穿整个数据结构的一个比较重要的一种结构,它的重要性不言而喻! 讲到树!一般都是讨论二叉树,而关于二叉树的定义以及概念这里不做陈诉,可自行搜索. 在C语言里面需要实现一个二叉树,我们需要 ...

  2. 二叉树各种相关操作(建立二叉树、前序、中序、后序、求二叉树的深度、查找二叉树节点,层次遍历二叉树等)(C语言版)

    将二叉树相关的操作集中在一个实例里,有助于理解有关二叉树的相关操作: 1.定义树的结构体: typedef struct TreeNode{ int data; struct TreeNode *le ...

  3. c++排序二叉树的出现的私有函数讨论,以及二叉树的删除操作详解

    c++排序二叉树的出现的私有函数讨论, 以及二叉树的删除操作详解 标签(空格分隔): c++ 前言 我在c++学习的过程中, 最近打了一个排序二叉树的题目,题目中出现了私有函数成员,当时没有理解清楚这 ...

  4. Java 二叉树遍历相关操作

    BST二叉搜索树节点定义: /** * BST树的节点类型 * @param <T> */ class BSTNode<T extends Comparable<T>&g ...

  5. java实现二叉树的相关操作

    import java.util.ArrayDeque; import java.util.Queue; public class CreateTree { /** * @param args */ ...

  6. 二叉树JAVA实现

    为了克服对树结构编程的畏惧感和神秘感,下定决心将二叉树的大部分操作实现一遍,并希望能够掌握二叉树编程的一些常用技术和技巧.关于编程实现中的心得和总结,敬请期待!~ [1]  数据结构和表示: 二叉树的 ...

  7. 【数据结构】之二叉树的java实现

    转自:http://blog.csdn.net/wuwenxiang91322/article/details/12231657 二叉树的定义: 二叉树是树形结构的一个重要类型.许多实际问题抽象出来的 ...

  8. [STL源码剖析]RB-tree的插入操作

    RB-tree的性质 对于RB-tree,首先做一个了解,先看一张维基百科的RB-tree: 再看RB-tree的性质: 性质1. 节点是红色或黑色. 性质2. 根是黑色,所有叶子都是黑色(叶子节点指 ...

  9. C实现二叉树(模块化集成,遍历的递归与非递归实现)

    C实现二叉树模块化集成 实验源码介绍(源代码的总体介绍):header.h : 头文件链栈,循环队列,二叉树的结构声明和相关函数的声明.LinkStack.c : 链栈的相关操作函数定义.Queue. ...

随机推荐

  1. 使用IntelliJ IDEA,gradle开发Java web应用步骤

    最近 正在学习gradle构建工具的使用,看了一堆的文档,有点一知半解,索性动作实践一把,在以后的自己的项目中尝试使用看看.目前手头用的是IntelliJ IDEA 14,搭建了一天终于明白怎么集成g ...

  2. sqlconnection dispose()与close()的区别

    区别: IDispose接口可以通过Using关键字实现使用后立刻销毁,因此,Dispose适合只在方法中调用一次SqlConnection对象,而Close更适合SqlConnection在关闭后可 ...

  3. 在Ubuntu18.04的Docker中安装Oracle镜像及简单使用

    一.软件环境: 1.OS:Ubuntu 18.04 2.已安装了Docker 二.安装Oracle镜像的过程 1.切换到root账号下,如果是普通账号,下面操作指令前面加sudo 2.搜索oracle ...

  4. Visual Studio工具 vcpkg简介

    博客参考: https://blog.csdn.net/cjmqas/article/details/79282847#43-%E7%A7%BB%E9%99%A4%E5%85%A8%E5%B1%80% ...

  5. Java程序设计11——GUI设计与事件处理B

    4 Java事件模型的流程 为了使图形界面能够接收用户的操作,必须给各个组件加上事件处理机制. 在事件处理的过程中,主要涉及3类对象: 1.Event Source(事件源):事件发生的场所,通常就是 ...

  6. jquery中prop()和attr()的区别

    相比attr,prop是1.6.1才新出来的,两者从中文意思理解,都是获取/设置属性的方法(attributes和properties).只是,window或document中使用.attr()方法在 ...

  7. Plupload 上传详细讲解,Plupload 多实例上传,Plupload多个上传按钮--推荐使用

    今天帮朋友解决  Plupload  上传的问题,查了很多资料,资料还是挺全的,但是有点零零散散的,故整理好,合并发出来. 本教程包括: Plupload  上传详细讲. Plupload  多实例上 ...

  8. AppleScript: Handler

    AppleScript绝对是个奇葩的存在!不管功能有多强大. Handler有两种,一种是和OC类似的使用Label参数,一种是和javascript类似的使用括号把一堆参数都放在里面的. label ...

  9. EBS单实例上所有正在运行的并发请求以及请求目前的状态

    --EBS单实例上所有正在运行的并发请求以及请求目前的状态---一个实例上运行的所有并发请求的总结和他们目前的状态以及等待状态    select w.seconds_in_wait "Se ...

  10. 手动编译安装lamp之mysql

    转自马哥教育的讲课文档 二.安装mysql-5.5.28 1.准备数据存放的文件系统 新建一个逻辑卷,并将其挂载至特定目录即可.这里不再给出过程. 这里假设其逻辑卷的挂载目录为/mydata,而后需要 ...