专业术语:
节点 父节点 根节点 子孙 堂兄弟
深度:
从根节点到最底层节点的层数称为深度
叶子节点:
没有子节点的节点称为叶子节点
非终端节点:
实际就是非叶子节点
度:
子节点的个数称为度
树的分类:
一般树
任意一个节点的子节点个数都不受限制
二叉树
任意一个节点的子节点的个数最多是两个 且子节点的位置不可更改
分类:
一般二叉树
满二叉树
在不添加树的层数的情况下每个子节点都满了不能再多一个节点
完全二叉树
如果只删除了满二叉树最底层最右边的连续若干个节点这样形成的二叉树就是完全二叉树
满二叉树是完全二叉树的一个特例 完全二叉树包含满二叉树
森林
N个互不相交的树的集合
 
树的存储:
二叉树的存储
连续存储[完全二叉树] 数组存储方式
优点 查找某个父节点和子节点(包括判断有无子节点)速度很快
缺点 很耗费内存空间
链式存储[链表存储]
一般树的存储
双亲表示法
求父节点方便
孩子表示法
求子节点方便
双亲孩子表示法
求父节点子节点都方便
二叉树表示法
一般树转二叉树来存储具体转换方法:
设法保证任意一个节点左指针域指向它的第一个孩子节点
右指针域指向它的下一个兄弟节点
只要满足此条件就能把普通树转换成二叉树
一个普通的树转换成二叉树 一定没有右子树
森林的存储
和一般树转换二叉树一样
 
树的操作:
二叉树每个子节点可以没有子节点如果有最多是2个
二叉树遍历分为三种
中序遍历
左根右-----(先遍历左子树-然后是根节点-再然后遍历右子树)
前序遍历
根左右-----(先遍历跟节点-然后是左子树-再然后遍历右子树)
后序遍历
左右根-----(先遍历左子树-然后是右子树-再然后遍历根节点)
已知两种遍历求原始二叉树
通过先中 后中 两种遍历可以推算二叉树的原始二叉树
通过 先后遍历无法还原原始二叉树
 
 
 
 
 #ifndef __MYBTREE_H__
#define __MYBTREE_H__
#include <Windows.h>
class Monster
{
public:
int ID;
int Level;
char Name[];
public:
Monster(){}
Monster(int ID,int Level,char* Name)
{
this->ID = ID;
this->Level = Level;
memcpy(&this->Name,Name,strlen(Name)+);
}
}; template<class T>
class TreeNode{
public:
T element; //当前节点存储的数据
TreeNode<T>* pLeft; //指向左子节点的指针
TreeNode<T>* pRight; //指向右子节点的指针 TreeNode(T& ele){
//初始化Node节点
memset(&element,,sizeof(TreeNode));
//为元素赋值
memcpy(&element,&ele,sizeof(T));
pLeft = pRight = NULL;
}
}; template<class T>
class BSortTree{
public:
BSortTree(); //构造函数
~BSortTree(); //析构函数
public:
void InOrderTraverse(TreeNode<T>* pNode); //中序遍历
void PreOrderTraverse(TreeNode<T>* pNode); //前序遍历
void PostOrderTraverse(TreeNode<T>* pNode); //后序遍历
TreeNode<T>* GetRoot(); //返回根节点
int GetDepth(TreeNode<T>* pNode); //返回某个节点的高度/深度
void clear(TreeNode<T>* pNode); //清空所有节点
private:
void Init();
private:
TreeNode<T>* m_pRoot; //根结点指针
int size; //树中元素总个数
}; template<class T>
BSortTree<T>::BSortTree()
{
Init();
}
template<class T>
BSortTree<T>::~BSortTree(){ //释放所以节点空间
if (NULL != m_pRoot)
{
clear(m_pRoot);
} }
template<class T>
void BSortTree<T>::clear(TreeNode<T>* pNode) //清空所有节点
{
if (NULL != pNode)
{
clear(pNode->pLeft);
clear(pNode->pRight);
delete pNode;
pNode = NULL;
}
}
template<class T>
void BSortTree<T>::Init()
{ Monster m1(,,"刺猬");
Monster m2(,,"野狼");
Monster m3(,,"野猪");
Monster m4(,,"士兵");
Monster m5(,,"火龙");
Monster m6(,,"独角兽");
Monster m7(,,"江湖大盗"); TreeNode<Monster>* n1 = new TreeNode<Monster>(m1);
TreeNode<Monster>* n2 = new TreeNode<Monster>(m2);
TreeNode<Monster>* n3 = new TreeNode<Monster>(m3);
TreeNode<Monster>* n4 = new TreeNode<Monster>(m4);
TreeNode<Monster>* n5 = new TreeNode<Monster>(m5);
TreeNode<Monster>* n6 = new TreeNode<Monster>(m6);
TreeNode<Monster>* n7 = new TreeNode<Monster>(m7); m_pRoot = n5;
n5->pLeft = n4;
n5->pRight = n6;
n4->pLeft = n1;
n1->pRight = n2;
n6->pLeft = n3;
n3->pRight = n7;
size = ;
/*
5 4 6 1 3 2 7 */
}
template<class T>
TreeNode<T>* BSortTree<T>::GetRoot()
{
return m_pRoot;
}
template<class T>
int BSortTree<T>::GetDepth(TreeNode<T>* pNode)
{
if(pNode==NULL)
{
return ;
}
else
{
int m = GetDepth(pNode->pLeft);
int n = GetDepth(pNode->pRight);
return (m > n) ? (m+) : (n+);
}
}
template<class T>
void BSortTree<T>::InOrderTraverse(TreeNode<T>* pNode)
{
//中序遍历所有怪物,列出怪的名字
if (NULL != pNode)
{
InOrderTraverse(pNode->pLeft);
printf("%s--%d\r\n",((Monster)pNode->element).Name,((Monster)pNode->element).ID);
InOrderTraverse(pNode->pRight);
} } template<class T>
void BSortTree<T>::PreOrderTraverse(TreeNode<T>* pNode)
{ //前序遍历所有怪物,列出怪的名字
if (NULL != pNode)
{
printf("%s--%d\r\n",((Monster)pNode->element).Name,((Monster)pNode->element).ID);
PreOrderTraverse(pNode->pLeft);
PreOrderTraverse(pNode->pRight); } } template<class T>
void BSortTree<T>::PostOrderTraverse(TreeNode<T>* pNode)
{ //后序遍历所有怪物,列出怪的名字
if (NULL != pNode)
{
PostOrderTraverse(pNode->pLeft);
PostOrderTraverse(pNode->pRight);
printf("%s--%d\r\n",((Monster)pNode->element).Name,((Monster)pNode->element).ID); } }
#endif //__MYBTREE_H__

调用的例子

 #include <stdio.h>
#include <stdlib.h>
#include "MyBTree.h"
#include <stack>
int main(void)
{
Stack<BSortTree> BSortTree<Monster>* P =new BSortTree<Monster>();
P->InOrderTraverse(P->GetRoot());
printf("-----------------------\r\n");
P->PreOrderTraverse(P->GetRoot());
printf("-----------------------\r\n");
P->PostOrderTraverse(P->GetRoot());
delete P;
system("pause");
return ;
}

c++简单实现二叉树的更多相关文章

  1. golang简单实现二叉树的数据添加和遍历

    代码实现 package tree import "fmt" type Node struct { elem interface{} left, right *Node } typ ...

  2. C#实现二叉树的各种遍历

    1. 引言 在实际的项目中,树还是用的比较多的一种,尤其是对于具有层次结构的数据.相信很多人都学过树的遍历,比如先序遍历,后序遍历等,利用递归还是很容易理解的. 今天给大家介绍下二叉树的几种遍历算法, ...

  3. 九度oj 1184 二叉树遍历

    原题链接:http://ac.jobdu.com/problem.php?pid=1184 简单的二叉树重建,遍历. 如下: #include<cstdio> #include<cs ...

  4. [九度OJ]1078.二叉树的遍历(重建)

    原题链接:http://ac.jobdu.com/problem.php?pid=1078 题目描述: 二叉树的前序.中序.后序遍历的定义:前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其 ...

  5. Invert a binary tree 翻转一棵二叉树

    Invert a binary tree 翻转一棵二叉树 假设有如下一棵二叉树: 4  / \   2    7  / \   / \ 1  3 6  9翻转后: 4     /    \    7 ...

  6. [数据结构]C语言二叉树的实现

    树和图是数据结构中比较麻烦的东西,里面涉及的概念比较多,也最有用, 就比如一般树广泛应用于人工智能的博弈上,而基于图的广度优先和深度优先搜索也广泛应用于人工智能寻路上面 首先我们要把树进行分类: &g ...

  7. List集合就这么简单【源码剖析】

    前言 声明,本文用得是jdk1.8 前一篇已经讲了Collection的总览:Collection总览,介绍了一些基础知识. 现在这篇主要讲List集合的三个子类: ArrayList 底层数据结构是 ...

  8. 一步一步写数据结构(二叉树的建立和遍历,c++)

    简述: 二叉树是十分重要的数据结构,主要用来存放数据,并且方便查找等操作,在很多地方有广泛的应用. 二叉树有很多种类,比如线索二叉树,二叉排序树,平衡二叉树等,本文写的是最基础最简单的二叉树. 思路: ...

  9. 二叉树的遍历--C#程序举例二叉树的遍历

    二叉树的遍历--C#程序举例二叉树的遍历 关于二叉树的介绍笨男孩前面写过一篇博客 二叉树的简单介绍以及二叉树的存储结构 遍历方案 二叉树的遍历分为以下三种: 先序遍历:遍历顺序规则为[根左右] 中序遍 ...

随机推荐

  1. 安装pip3遇到:E: Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).

    安装pip3遇到:E: Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution). 具 ...

  2. 阿里开源!轻量级深度学习端侧推理引擎 MNN

    阿里妹导读:近日,阿里正式开源轻量级深度学习端侧推理引擎“MNN”. AI科学家贾扬清如此评价道:“与 Tensorflow.Caffe2 等同时覆盖训练和推理的通用框架相比,MNN 更注重在推理时的 ...

  3. L05 Laravel 教程 - 电商实战

    https://laravel-china.org/courses/laravel-shop https://laravel-china.org/topics/13206/laravel-shop-c ...

  4. hdu 1596 find the safest road (变形SP && dij+heap)

    Problem - 1596 变形最短路问题,给出邻接矩阵,要求求出给定点对间安全率最大值. 这题可以用dijkstra+heap来做.对于每一个查询,做一次dij即可. 代码如下: #include ...

  5. Jieba分词包(一)——解析主函数cut

    1. 解析主函数cut Jieba分词包的主函数在jieba文件夹下的__init__.py中,在这个py文件中有个cut的函数,这个就是控制着整个jieba分词包的主函数.    cut函数的定义如 ...

  6. jq杂项方法/工具方法----isArray()

    https://www.cnblogs.com/sandraryan/ $.isArray()函数用于判断指定参数是否是一个数组.返回布尔值. <!DOCTYPE html> <ht ...

  7. Java如何计算hashcode值

    在设计一个类的时候,很可能需要重写类的hashCode()方法,此外,在集合HashSet的使用上,我们也需要重写hashCode方法来判断集合元素是否相等. 下面给出重写hashCode()方法的基 ...

  8. 2004年NOIP普及组复赛题解

    题目涉及算法: 不高兴的津津:入门题: 花生采摘:贪心: FBI树:递归.DP求区间和: 火星人:模拟. 不高兴的津津 题目链接: 简单枚举. 遍历一遍,找到 \(a[i] + b[i]\) 最大的那 ...

  9. Java集合系统

    前言: 要想学习java的集合体系,就必须先了解java的集合框架,总的来说,分为Collection和Map体系. Collection集合框架: Map集合框架: 一. Collection接口 ...

  10. centos linux ip地址无法连接数据库,ssh登录服务器时必须使用22端口

    问题一:连接数据库时直接使用ip地址无法连接,必须使用ssh方式才能连接? 问题二:ssh登录服务器时必须使用22端口,在/etc/ssh/sshd_config中添加了10086端口,防火墙中已开启 ...