小小c#算法题 - 10 - 求树的深度
树型结构是一类重要的非线性数据结构,树是以分支关系定义的层次结构,是n(n>=0)个结点的有限集。关于树的基本概念不再作过多陈述,相信大家都有了解,如有遗忘,可翻书或去其他网页浏览以温习。
树中结点的最大层次数称为树的深度(Depth)或高度。
本文中以二叉树为例来讲述求树的深度的算法。
在算法开始之前,我们要有数据,即一棵树,树又是结点的集合。所以,应该先定义结点的数据结构(结点的基本属性和操作),然后再定义树的数据结构(树的基本属性和操作)。本文的重点不是讲如何去创建树的数据结构,所以一切从简,本文只是简单构造了结点的数据结构,创建一些结点,然后把这些结点按照逻辑关系关联起来,组成一棵树。而并没有专门去构造树的数据结构,如果要构造树的数据结构,应该有添加结点(InsertChild)的方法,求树的深度也应该作为树的一个方法存在。
下面是结点的类的定义:
class Node
{
public int Value
{
get;
set;
} public Node LeftChild
{
get;
set;
} public Node RightChild
{
get;
set;
}
}
接下来我们就可以定义一系列的结点,设置左右孩子结点形成分支结构的一棵树。下面是Main方法中的代码:
static void Main(string[] args)
{
// 创建结点,并通过设置左右孩子组成一棵树
Node root = new Node() { Value = };
Node level21 = new Node() { Value = };
Node level22 = new Node() { Value = };
Node level31 = new Node() { Value = };
Node level32 = new Node() { Value = };
Node level33 = new Node() { Value = };
Node level41 = new Node() { Value = }; root.LeftChild = level21;
root.RightChild = level22;
level21.LeftChild = level31;
level22.LeftChild = level32;
level22.RightChild = level33;
level32.RightChild = level41; // 求树的深度
//int treeDepth = GetTreeDepth(root); //递归求解
int treeDepth = GetTreeDepthByLoop(root); //非递归求解
Console.WriteLine(treeDepth);
Console.ReadKey();
}
通过以上代码,我们构成了如下的一棵树:
可以看出,这棵树的深度是4。下面就来讨论求树的深度的算法。
1.递归求解:
采用递归可以把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。拿上面生成的树来说,如果要求其深度,那么只要取其左子树(以2为根结点的子树)和右子树(以3为根结点的子树)深度的最大值,然后加1即可。由此递归处理下去,直到一棵树只有一个根结点的时候,可知其深度为1,这里是递归的边界条件,这时可以返回上一层的递归。
下面是代码:
private static int GetTreeDepth(Node root)
{
if (root == null)
{
return ;
}
else
{
int leftTreeDepth = GetTreeDepth(root.LeftChild);
int rightTreeDepth = GetTreeDepth(root.RightChild); if (leftTreeDepth >= rightTreeDepth)
{
return leftTreeDepth + ;
}
else
{
return rightTreeDepth + ;
}
}
}
想不通的同学可以拿上面创建好的树来手动地走一遍。
2.直接求解:
直接求解的思想也十分简单,我们可以称之为广度优先遍历。从根结点开始,得到其所有孩子结点,放到一个集合A中,这个集合A中即第二层(根结点为第一层)的所有结点。如果这个集合A不为空,说明其深度至少为2,这时,我们把记录树的深度的变量加1,由初始的1变为2。然后我们遍历这个集合A中的所有结点,即遍历树的第二层的结点,同时把第二层中所有结点的子结点放到另外一个集合B中,这样,另外一个集合B中存放的就是第三层的结点。如果集合B不为空,那么记录深度的变量再加1。这时清空集合A,准备存放下一层的结点,如此循环下去,其间集合A,B交替使用,一个用来存放正在遍历的结点,一个存放下一次要遍历的孩子结点,直到当某一层的结点数为0时,说明已经到树的最底层,可以退出循环了,记录深度的变量此时的值就是树的深度。
代码如下:
// 循环实现,广度优先遍历
private static int GetTreeDepthByLoop(Node root)
{
if (root == null) return ; int depth = ;
List<Node> nodes1 = new List<Node>();
List<Node> nodes2 = new List<Node>();
List<Node> temp; nodes1.Add(root); while (true)
{
foreach (Node n in nodes1)
{
if (n.LeftChild != null)
{
nodes2.Add(n.LeftChild);
} if (n.RightChild != null)
{
nodes2.Add(n.RightChild);
}
} if (nodes2.Count > ) depth++;
else return depth; nodes1.Clear();
temp = nodes1;
nodes1 = nodes2;
nodes2 = temp;
}
}
}
关于main方法中调用上述两种方法的代码,在给出创建树的代码时已经一并给出。
小小c#算法题 - 10 - 求树的深度的更多相关文章
- 小小c#算法题 - 11 - 二叉树的构造及先序遍历、中序遍历、后序遍历
在上一篇文章 小小c#算法题 - 10 - 求树的深度中,用到了树的数据结构,树型结构是一类重要的非线性数据结构,树是以分支关系定义的层次结构,是n(n>=0)个结点的有限集.但在那篇文章中,只 ...
- PAT-1021 Deepest Root (25 分) 并查集判断成环和联通+求树的深度
A graph which is connected and acyclic can be considered a tree. The height of the tree depends on t ...
- LeetCode Maximum Depth of Binary Tree (求树的深度)
题意:给一棵二叉树,求其深度. 思路:递归比较简洁,先求左子树深度,再求右子树深度,比较其结果,返回:max_one+1. /** * Definition for a binary tree nod ...
- 算法题:求一个序列S中所有包含T的子序列(distinct sub sequence)
题: 给定一个序列S以及它的一个子序列T,求S的所有包含T的子序列.例: S = [1, 2, 3, 2, 4] T = [1, 2, 4] 则S的所有包含T的子序列为: [1, 2, 3, 2, 4 ...
- 小小c#算法题 - 12 - Joseph Circle(约瑟夫环)
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数(从1开始报数),数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又 ...
- 小小c#算法题 - 9 - 基数排序 (Radix Sort)
基数排序和前几篇博客中写到的排序方法完全不同.前面几种排序方法主要是通过关键字间的比较和移动记录这两种操作来实现排序的,而实现基数排序不需要进行记录项间的比较.而是把关键字按一定规则分布在不同的区域, ...
- 小小c#算法题 - 7 - 堆排序 (Heap Sort)
在讨论堆排序之前,我们先来讨论一下另外一种排序算法——插入排序.插入排序的逻辑相当简单,先遍历一遍数组找到最小值,然后将这个最小值跟第一个元素交换.然后遍历第一个元素之后的n-1个元素,得到这n-1个 ...
- [面试算法题重做]求1+2+...+n
题目:求1+2+…+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字以及条件判断语句(A?B:C). 不能用条件语句,基本上只有考虑递归. 常规解法: 利用构 ...
- FCC JS基础算法题(10):Falsy Bouncer(过滤数组假值)
题目描述: 删除数组中的所有假值.在JavaScript中,假值有false.null.0."".undefined 和 NaN. 使用filter方法,过滤掉生成的 Boolea ...
随机推荐
- leetcode_sql_2,183
183. Customers Who Never Order Suppose that a website contains two tables, the Customers table and t ...
- Equation
You are given an equation: Ax2 + Bx + C = 0. Your task is to find the number of distinct roots of th ...
- word 2007,以不同颜色突出显示文本的快捷键,highlight命令
命令:highlight 默认快捷键:Ctrl+Alt+H 查询或自定义快捷键的方法: 打开一个文档→单击左上角的office图标→word选项 左边的列表中选择自定义→在右边的窗口中,底部有个“ ...
- jquery-post 异常
报错:Client closed connection before receiving entire response 前端请求: $.ajax({ type : 'POST' , url : '/ ...
- iOS 【资源篇】
iOS9开发入门教程索引 Objective-C视频教程 O-c Blog 社区 畅游 http://www.9ria.com/ 苹果中文开发社区 http://www.cocoachina.co ...
- [转] CentOS系统目录学习
最近初学Linux 对linux的目录产生了很多疑问,看到这篇文章,让我顿时对目录有了一个清晰的认识!推荐给大家! ------------------------------------------ ...
- Java学习之SpringMVC零配置实践
概述:本实践主要是对SpringMVC的主要功能做了一个大概的体验,将原来的SpringMVC的大量配置改成用SpringBoot进行集成,做到了零XML配置,本次实践分为两个部分,一部分为基本功能实 ...
- qq图片选择效果的处理
QQ中图片鼠标一选择,整个图片就像加了个阴影一样,这个效果一般人都不会注意,突然没事测试了一下,原来qq是把原来每个像素的颜色变成了相反的颜色. 电脑中的三原色为0-255,中间值为128,以中间值为 ...
- python学习笔记(一):python简介和入门
最近重新开始学习python,之前也自学过一段时间python,对python还算有点了解,本次重新认识python,也算当写一个小小的教程.一.什么是python?python是一种面向对象.解释型 ...
- CPU, PSU, SPU的区别
It all started in January 2005 with Critical Patch Updates (CPU). Then Patch Set Updates (PSU) were ...