《算法问题实战策略》-chaper21-树的实现和遍历
这一章节开始介绍一个数据结构中的一个基本概念——树。
我们从数据结构的解读来解释树结构的重要性,现实世界的数据除了最基本的线性结构(我们常用队列、数组和链表等结构表征),还有一个重要的特性——层级结构需要我们去表征,例如世界杯的对阵表、遗传系谱图等等,这时候我们基于对现实世界的抽象,会很自然的理解为什么会有树这样一个数据结构。
而树这种数据结构也是能够分类的,我们将每个节点记录某种抽象的概念或者具象的事物,这样用来表征一种从属关系,我们称其为抽象型数据结构的树。或者将每个节点储存一些数据,基于这棵树我们能够完成检索查找之类的操作,我们称其为检索型数据结构的树。
关于树的基本的术语和其中的基本概念,这里不再累述,读者可以通过查找离散数学或者图论的资料了解。
树的实现:
既然了解到了树存在的必要性和重要性,下面我们就应该去关注怎样实现一棵树了。在《啊哈算法》中,作者介绍了用一维数组实现的二叉树,这是基于二叉树一些非常特殊的形式,但是对于更加一般的情况的多叉树呢?我们需要采用更加一般的方法。对于树中的每一个节点,我们很关注如下集合很有价值的数据:它的父节点?它的子节点?存在该节点的数据?关于它的父节点和子节点,其实就是需要我们表征一种“联系”,即通过该节点,我们能够轻松的找到和它关联的父节点和子节点,我们很容易便可以想到指针。而基于一维数组实现的二叉树,就是二叉树的基本性质,通过为节点标号从而实现了指针的作用。
通过上面的分析,我们能够定义树节点的结构体。
struct Treenode
{
<data>
TreeNode* parent;
vector<TreeNode*> children;
};
树的遍历:
树本质上也是一种图,因此这里采用基本的深搜就可以完成对树的遍历。
void printLabels(TreeNode* root)
{
cout<< root-> <data><<endl;
for(int i = ;i < root->chilren.size();i++)
printLabels(root->children[i]);
}
基于对树的遍历,我们同时可以完成对树的高度的计算。
int height(TreeNode* root)
{
int h = ;
for(int i = ;i < root->children.size();i++)
h = max(h,+height(root->children[i]));
return h;
}
关于一个树结构的一个简单建模:
Q:中世纪时,为了更好的首尾保护更多领地,城市和要塞之间都具有多层城墙。偏执狂领主建筑的Strawgoh要塞达到了这中间城模式的极致。下图是这种要塞的结构图。那么现在给出一个要塞的图,两个城市之间没有门只能通过梯子翻越城墙,请问再给出的城墙图中,从一个城市到另一个城市最多翻阅多少城墙?
Input:
将每个城市看成一个圆,然后程序会给出n个圆的圆心和半径用来表示这个城墙结构。
用树建立起来的解题模型:这道问题从原始的图上来看并不好直观的得到它会与树联系起来,但是我们进一步的看这个图,是否像集合论当中的维恩图,而维恩图就是典型的层级结构,这正与树结构能够表征的东西呼应起来。如果基于树结构看这个问题,我们就能够将问题化约成,求解树结构的最长路径,也就是树的深度。这个在前面介绍“树的实现和遍历”当中曾经简单的介绍过它的实现方法。
显然整体的思路有了,下面我们面临的最大问题就是,如何基于题目给出的数据,建立这样一棵树结构?
建树的方法:首先基于一个基本的递归过程,也可以说成一个深度优先建树的过程。我们从根节点开始,假设我们已经有了一个判断两个城市是否是父子关系的函数,我们能够写出如下的过程:
TreeNode* getTree(int root)
{
TreeNode* ret = new TreeNode();//指向该节点的指针
for(int i = ;i < n;i++)
if(isChild(root,i))
ret -> children.push_bcak(getTree(ch));//树节点数据中储存儿子结点的向量表
return ret;
}
那么好了,下面我们面临的问题就变成了如何设计判断两个城市之间是否是父子关系的isChild()函数了。如何判断两个点在树结构中是否是父子关系呢?通过观察我们能够发现,必须两个区域是直接的包含关系,即对于圆B,A,如果B内含与A并且不存在这样一个圆C使得圆C内含与A且B内含于C。清楚了这一点,在拿到两个区域判断其双方是否是父子关系的时候,首先我们当然要利用简单的几何知识要判断他们是否是包含关系,随后我们通过穷举的方法来遍历剩下的所有区域由此来判断是否存着这样一个上文中提到的区域C,即我们能够写出如下的简单代码。
int n , y[],x[],radius[];
bool inclose(int a , int b)//判断圆b是否在圆a的内部
{
double dis;//圆心距
dis = sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
if(radius[b]-radius[a] >= dis)
return true;
else
return false;
}
bool isChild(int parent , int child)
{
if(!inclose(parent,child)) return false;
int flag = ;
for(int i = ;i < n;i++)
{
if(i == parent || i == child) continue;
if(inclose(parent,i) && inclose(i,child)) {flag = ;break;}
}
if(flag) return true;
else return false;
}
《算法问题实战策略》-chaper21-树的实现和遍历的更多相关文章
- 算法问题实战策略 PICNIC
下面是另一道搜索题目的解答过程题目是<算法问题实战策略>中的一题oj地址是韩国网站 连接比较慢 https://algospot.com/judge/problem/read/PICNIC ...
- 《算法问题实战策略》-chaper7-穷举法
关于这一章节<算法实战策略>有一段概述问题,我认为对于编程人员来说非常有价值,故在这里进行如下的摘抄: 构想算法是很艰难的工作.相比大家都经历过,面对复杂的要求只是傻乎乎地盯着显示器,或者 ...
- 《算法问题实战策略》-chaper13-数值分析
这一章节主要介绍我们在进行数值分析常用的二分.三分和一个近似求解区间积分的辛普森法. 首先介绍二分. 其实二分的思想很好理解并且笔者在之前的一些文章中也有所渗透,对于二次函数甚至单元高次函数的零点求解 ...
- 《算法问题实战策略》-chaper32-网络流
基本的网络流模型: 在图论这一块初步的应用领域中,两个最常见的关注点,其一时图中的路径长度,也就是我们常说的的最短路径问题,另一个则是所谓的“流问题”. 流问题的基本概念: 首先给出一张图. 其实所谓 ...
- 算法问题实战策略 MEETINGROOM 附一份tarjan模板
地址 https://algospot.com/judge/problem/read/MEETINGROOM 解答 2-sat 代码样例过了 没有ac. 我又没有正确代码对拍..... 已确认是输出 ...
- 《算法问题实战策略》——chaper9——动态规划法技巧
Q1: 数字游戏: 两个人(A.B)用n个整数排成的一排棋盘玩游戏,游戏从A开始,每个人有如下操作: (1) 拿走棋盘最右侧或者最左侧的棋子,被拿走的数字从棋盘中抹掉. (2) 棋盘中还剩 ...
- 《算法问题实战策略》-chaper8-动态规划法
Q1:偶尔在电视上看到一些被称为“神童”的孩子们背诵小数点以后几万位的圆周率.背诵这么长的数字,可利用分割数字的方法.我们用这种方法将数字按照位数不等的大小分割后再背诵. 分割形式如下: 所有数字都相 ...
- 《算法问题实战策略》-chaper14-整数论
Lucas定理: 在组合计数问题中,我们常面临组合数C(n,m)过大而无法直接计算的困境,那么这里的Lucas定理给出了一个较大组合数进行取余运算的一种递归算法. 什么是Lucas定理? Lucas定 ...
- 算法问题实战策略 QUADTREE
地址 https://algospot.com/judge/problem/read/QUADTREE 将压缩字符串还原后翻转再次压缩的朴素做法 在数据量庞大的情况下是不可取的 所以需要在压缩的情况下 ...
随机推荐
- HBuilder+移动APP开发实例
mui: 官网:http://dcloudio.github.io/mui/ 说明:一般要把官网内容通读一遍,这是开发的基础 开始 1.新建项目 在首页点击新建移动App,如下: 或者在项目管理器内右 ...
- 详细查看数据库SQL执行计划
DBCC DROPCLEANBUFFERS 清除数据缓存DBCC FREEPROCCACHE 清除执行计划缓存 SET SHOWPLAN_XML ON 此语句导致 SQL Server 不执行 Tr ...
- 项目报错,tomcat中引起
1.项目报错,但发现工程并没有错.此刻错误应该定位如下,即工程里面引用的jar可能有错,可能是路劲变了....
- js定位navigator.geolocation
一.简介 html5为window.navigator提供了geolocation属性,用于获取基于浏览器的当前用户地理位置. window.navigator.geolocation提供了3个方法分 ...
- 4种检测是否支持HTML5的方法,你知道几个?
4种检测是否支持HTML5的方法,你知道几个? 1,检查特定的属性是否存在于全局的对象里面,比如说window或navigator. 比如geolocation,它是HTML5新加支持的新特性:它是由 ...
- python内置字符串操作方法
1.capitalize() S.capitalize()->string 首字母大写,其余字母小写. str='A222aaA' str.capitalize()#首字母大写,其余字母小写. ...
- python 时间戳
import timeprint time.time()输出的结果是(单位:s):1395421406.39 x = time.localtime(x) x = time.strftime('%Y-% ...
- windows server 2012 iis8.0部署mvc报错
一开始以为需要在服务器装mvc在很多论坛找过也问了朋友都说需要装mvc,经过两天研究是不需要装mvc的只需要在项目的bin文件夹下放入下面三个dll. 未能加载文件或程序集“System.Web.Ht ...
- EntityFramework Core使用PostgreSQL
EntityFramework Core使用PostgreSQL 0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用 ...
- iPad和iPhone开发的比较
一.iPad简介 1.什么是iPad 一款苹果公司于2010年发布的平板电脑 定位介于苹果的智能手机iPhone和笔记本电脑产品之间 跟iPhone一样,搭载的是iOS操作系统 2.iPad的市场情况 ...