数据结构(三)—树

树的定义

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根在上,而叶在下的。

有一个特殊的结点,称为根结点,根节点没有前驱结点。除根节点外,其余结点被分成m(m > 0)个互不相交的集合T1、T2、…… 、Tm,其中每一个集合Ti(1 <= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,但可以有0个或多个后继。

树的样例


这里一颗树有且只有一个根节点(图中:A),然后以B为节点的数称为数A的左子树,然后以C为节点的称为右子树。
我们在这里介绍一些树的概念

树的概念

(1)结点的度:一个节点含有的子树的个数称为该节点的度;A的为2,即B、C。

(2)叶结点:度为0的节点称为叶结点;如上图:K、J、L…等为叶结点。

(3)双亲结点或父结点:若一个节点含有子结点,则这个结点称为其子结点的父结点;如上图:A是B的父结点。

(4)孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点;如上图:B是A的孩子节点。

(5)兄弟结点:具有相同父结点的结点互称为兄弟结点; 如上图:B、C是兄弟结点。

(6)树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为3。

(7)结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推。

(8)树的高度或深度:树中结点的最大层次; 如上图:树的高度为4。

(9)节点的祖先:从根到某一结点所经分支上的所有结点;如上图:D、A是K的祖先;A是所有结点的公共祖先。

(10)子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙。

(11)森林:多棵互不相交的树的集合称为森林。

树的初始化

typedef int DataType;
struct Node
{struct Node* firstChild1; // 第一个孩子结点struct Node* pNextBrother; // 指向其下一个兄弟结点DataType data; // 结点中的数据域
};

二叉树

二叉树的概念及其特点

概念

一棵二叉树是结点的一个有限集合,该集合为空,或者是由一个根节点加上两棵称为左子树和右子树的二叉树组成。

二叉树的特点:

(1)每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
(2)二叉树的子树有左右之分,其子树的次序不能颠倒。

二叉树分类

二叉树分为完全二叉树,满二叉树,及普通二叉树。
这里我们主要讲完全二叉树和满二叉树

满二叉树

1)满二叉树

每一层的结点数都达到最大值,则这个二叉树就是满二叉树。
也就是说,如果一个二叉树的层数为K(根节点是第1层),且结点总数是(2^k) -1 ,则它就是满二叉树。


2)完全二叉树

完全二叉树是由满二叉树而引出来的。对于深度为K的、有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 满二叉树是一种特殊的完全二叉树。
也就是说:完全二叉树的叶子结点只能出现在最下层和次下层,且最下层的叶子结点从左到右连续;前K-1层是满的二叉树。

二叉树的实现

typedef int BTData;
typedef struct BinaryTree
{BTData x;//数据域struct BinaryTree* left;//左子树的根节点struct BinaryTree* right;//右子树的根节点
}BTNode;

二叉树的遍历
前序遍历

//前序遍历:根 左子树 右子树
void PrevOrder(BTNode* root)
{//root为空是递归的终止条件if (root == NULL){printf("NULL ");return;}printf("%c ", root->x);//访问根,这里进行打印操作,也可进行其他操作PrevOrder(root->left);//递归访问左子树PrevOrder(root->right);//递归访问右子树
}

中序遍历

//中序遍历:左子树 根 右子树
void InOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}InOrder(root->left);printf("%c ", root->x);InOrder(root->right);
}

后续遍历

//后序遍历:左子树 右子树 根
void PostOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}PostOrder(root->left);PostOrder(root->right);printf("%c ", root->x);
}

二叉树的操作

1)求某层节点个数

int TreeKLevelSize(BTNode* root, BTData k)
{if (root == NULL)return 0;//root != NULLif (k == 1)return 1;return TreeKLevelSize(root->left, k - 1) + TreeKLevelSize(root->right, k - 1);
}

2)一棵树的结点总个数

int TreeSize2(BTNode* root)
{//结点是空则为0,否则为左右子树的结点个数加上1(这个不为空的结点是1个结点)return root == NULL ? 0 : (TreeSize2(root->left) + TreeSize2(root->right) + 1);
}

3)一棵树的叶子结点个数

int LeafSize(BTNode* root)
{if (root == NULL)//空结点不计数return 0;else if (root->left == NULL && root->right == NULL)//是叶子结点计数return 1;elsereturn LeafSize(root->left) + LeafSize(root->right);
}

4)查找某个值

BTNode* TreeFind(BTNode* root, BTData x)
{BTNode* leftRet = NULL;BTNode* rightRet = NULL;if (root == NULL)//是空返回return NULL;if (root->x == x)//找到return root;//代码运行到这里说明root不是空,且root的值不为xleftRet = TreeFind(root->left, x);//去root的左子树找if (leftRet != NULL)//leftRet不是空说明找到了return leftRet;//代码运行到这里说明root不是空,且root的值不为x,且root的左子树中没有值为x的结点rightRet = TreeFind(root->right, x);if (rightRet != NULL)return rightRet;//代码运行到这里说明root不是空,且root的值不为x,且root的左右子树中均没有值为x的结点//说明树中没有值为x的结点,返回空return NULL;
}

树的搜索方式

广度优先搜索

广度搜索,顾名思义,就是更大范围内搜索,先访问完当前顶点的所有邻接点,然后再访问下一层的所有节点,该算法适用于解决最短、最小路径等问题,但是构建广度优先算法需要维护自己的队列。

广度搜索是同时搜索所有路径,相当于一层一层地搜索,就好比波浪的扩展一样。此搜索方法跟树的层次遍历类似,因此宽度搜索一般都用队列存储结构。

比如二叉树的层次遍历,我们大概会有如下几个步骤:

向Queue中放入root节点。
只要这个Queue中有元素就一直遍历。
每次遍历时,首先计算一下当前Queue里有多少个元素,这就是这棵树当前层级元素的数量,记作Size。
接下来从Queue中移除Size中的多个元素,对他们进行符合我们题目的一些操作。
移除每个节点时,把它们的子节点添加进Queue中。
只要Queue中还有元素,说明还有下一个层级,就一直重复步骤3去处理下一个层级。
图解

算法实现:

static const int dirs[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
void bfs(int row, int col) {if (row,col满足某种条件) {return;}int * queue = (int *)malloc(sizeof(int) * m * n);int head = 0;int tail = 0; 双指针实现队列先进先出queue[tail++] = row * n + col; while (head != tail) {int row = queue[head] / n;int col = queue[head] % n;head++;for (int i = 0; i < 4; i++) {int newRow = row + dirs[i][0], newCol = col + dirs[i][1];if 满足某种条件(newRow >= 0 && newRow < m && newCol >= 0 && newCol < n &&……) {对点进行某种操作操作queue[tail++] = newRow * n + newCol;}}}free(queue);
}

深度优先搜索

算法简介

DFS是可用于遍历树或者图的搜索算法,DFS与回溯法类似,一条路径走到底后需要返回上一步,搜索第二条路径。在树的遍历中,首先一直访问到最深的节点,然后回溯到它的父节点,遍历另一条路径,直到遍历完所有节点。图也类似,如果某个节点的邻居节点都已遍历,回溯到上一个节点。

深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。一般用栈数据结构来辅助实现DFS算法。根据深度优先搜索的特点,采用递归函数实现比较简单。但也可以不采用递归

图解:

代码实现

int dxy[4][2]={//模拟上下左右四个方向-1,0,//向上(x减一,y不变)1, 0,//向下0,-1,//向左0, 1//向右}
void dfs(int x0,int y0)
{if(x0,y0满足某种条件)//找到目标点{//执行操作如输出路径等return;}for(int i=0;i<4;i++)//遍历四个方向每一个分支,对每一个分支都进行深度搜索{int dx=dxy[i][0];//移动后的横坐标int dy=dxy[i][1];//移动后的纵坐标if(坐标越界||遇到障碍物||...)//不满足条件continue;//执行操作dfs(dx,dy)//深度遍历//遍历结束恢复操作}
}

数据结构(三)---树相关推荐

  1. 数据结构实验三 树的遍历生成树

    广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼418A)     2019年4月19日 学院 计算机科学与教育软件学院 年级.专业.班 计算机科学与技术 姓名 学号 实验课程名称 数据 ...

  2. 数据结构显示树的所有结点_您需要了解的有关树数据结构的所有信息

    数据结构显示树的所有结点 When you first learn to code, it's common to learn arrays as the "main data struct ...

  3. 数据结构-王道-树和二叉树

    [top] 树和二叉树 树:是\(N(N\geq0)\)个结点的有限集合,\(N=0\)时,称为空树,这是一种特殊情况.在任意一棵非空树中应满足: 有且仅有一个特定的称为根的结点. 当\(N>1 ...

  4. (八)数据结构之“树”

    数据结构之"树" 树是什么? 什么是深度/广度优先遍历? 深度优先遍历算法口诀 广度优先遍历算法口诀 二叉树的先中后序遍历 二叉树是什么 先序遍历算法口诀(根 > 左 > ...

  5. 【数据结构】数据结构三要素

    数据结构三要素 数据结构的三要素包括数据逻辑结构.数据存储结构和数据的运算. 数据逻辑结构 数据的逻辑结构是指数据元素之间的逻辑关系,即从逻辑关系上描述数据.它与数据的具体存储形式无关,是独立于计算机 ...

  6. 数据结构之树与二叉树

    数据结构之树与二叉树 1.树的概念及结构 1.1.什么是树? 树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合.树是递归定义的.之所以把它叫做树是因为它看起来像 ...

  7. 【图解数据结构】树和二叉树全面总结(上)

    目录 一.前言 二.树的概念和定义 三.二叉树 1.基本概念 2.基本形态 3.性质 4.满二叉树 5.完全二叉树 四.存储结构 1.顺序存储 2.二叉链表 3.三叉链表 一.前言 学习目标:理解树和 ...

  8. 高级数据结构-KD树

    高级数据结构-KD树 一.基本概念 KD树是一种对K维空间中的实例点进行存储以便对其进行快速检索的树形结构,表示对K维空间的一个划分 用于KNN算法的实现.给定一个目标点,利用KD树可以快速地查找出距 ...

  9. java 二叉树 红黑树_常见数据结构(二)-树(二叉树,红黑树,B树)

    常见数据结构(二)-树(二叉树,红黑树,B树) 标签: algorithms [TOC] 本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自course ...

  10. 【数据结构】初入数据结构的树(Tree)以及Java代码实现(一)

    初入数据结构的树(Tree)以及Java代码实现(一) 树的定义 为什么叫树? 树型结构的元素具有一对多关系 树的定义 树的一些基本概念 树的结点 后代,祖先 子树.空树 树的度与高(深度),结点的度 ...

最新文章

  1. CF660C Hard Process(尺取法)
  2. 使用Envoy代理的微服务模式,第二部分:超时和重试
  3. NFS还是iSCSI?关于VMware vSphere的存储连接的选择题
  4. Apache for windows虚拟主机配置方案(安全优化)
  5. atitit 信息化2.0概论 艾提拉解读版读书笔记.docx 目录 1. 企业信息化1.0时代 1.1.6 C/S模式和B/S模式的好坏 1.1.7 大集中的争议 1.1.8 没有解决的孤岛问
  6. JDK8 有关集合部分常用的语法
  7. linux命令行连接蓝牙音箱,树莓派4b连接蓝牙音箱/耳机播放音乐 命令行
  8. PHP运行的环境安装
  9. 单片机74LS138扩展中断
  10. python条形图的间距_如何减少堆积条形图中条形图之间的间距?
  11. Uva11500-Gambler's ruin
  12. 使用C++让鼠标指针抖动
  13. 新款Macbook Pro可以升级固态硬盘吗?
  14. 网站提供的下载IE8很慢 由于Microsoft 联机服务暂时不可用,SmartScreen筛选器无法检查此网站。...
  15. 阿里云短信api发送异常
  16. 系统辨识理论及MATLAB仿真——学习笔记(1)
  17. 图解Semaphore信号量之AQS共享锁-非公平模式
  18. CentOS 7 安装Elixir
  19. GmSSL制作国密算法自签证书和 HTTPS 配置
  20. 基于51单片机的智能环境监测光强火焰有害气体检测proteus仿真原理图PCB

热门文章

  1. 7-6 打妖怪 (10 分)
  2. CSS HTML 实现虚线横线分隔线
  3. 一行代码教你撩妹手到擒来❤html+css+js烟花告白3D相册(含音乐+可自定义文字)520表白/七夕情人节/求婚
  4. deepin 安装到移动硬盘_系统装机|硬盘里的Linux之deepin 20系统安装教程
  5. 如何画一条0.5px的边(细线)
  6. 谷歌colab“几键”运行图像超分辨率模型-ESRGAN,操作详解
  7. 原创仿虎哥说车抖音文案,抖音策划,虎哥说车文案背景音乐,房子租凭宣传文案
  8. 二代征信报告解读及信贷风控中的应用
  9. virtualbox虚拟机窗口大小调整
  10. 【xla】四、【构图阶段】BuildXlaOpsPass