当前位置: 首页 > news >正文

树与图的深度和广度优先遍历-java实现邻接表存储

树与图的深度优先遍历

树是特殊的无环连通图

图分成有向图和无向图(a-b 建a->b和b->a)

有向图可以用邻接矩阵(g[a][b] == a->b)和邻接表(存储每个点直接到达的所有点,h[N]存储每个位置头结点,每次加入边都在头结点加入)两种表达方式。

假设要构建一个无向图,包含边 1-2、1-3、2-4,执行过程如下:
初始状态:h[1]=-1、h[2]=-1、h[3]=-1、h[4]=-1,idx=0;
执行 add(1,2):
e[0]=2、ne[0]=-1(新节点指向空)、h[1]=0、idx=1;
此时 1 的邻接链表:1 -> 2;
执行 add(1,3):
e[1]=3、ne[1]=0(新节点指向原来的表头 0)、h[1]=1、idx=2;
此时 1 的邻接链表:1 -> 3 -> 2(头插法,新节点插在最前面);
执行 add(2,4):
e[2]=4、ne[2]=-1、h[2]=2、idx=3;
此时 2 的邻接链表:2 -> 4

对于邻接表

M=N*2
int h[N],e[M], ne[M], idx;
boolean st[N];//表示点是否被走过
void add(int a, int b){//给节点 a 新增一个邻接节点 be[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
// 需要标记数组st[N],  遍历节点的每个相邻的便
void dfs(int u) {st[u] = true; // 标记一下,记录为已经被搜索过了,下面进行搜索过程for (int i = h[u]; i != -1; i = ne[i]) {int j = e[i];if (!st[j]) {dfs(j);}}
}

树的重心

思路:

找出每个点去掉后,它的剩余联通块的点数的最大值,然后遍历得到其中最大值的最小值是多少

每次当前节点保存该节点的子树的点的数量,对于每个节点,父节点那一坨=n−sizen=n-size_n=nsizen

在这里插入图片描述

代码

import java.util.*;
public class Main{static int N = 100010,M = N * 2,idx,n;static int[] h = new int[N];static int[] e = new int[M];//存的是双倍,所以是Mstatic int[] ne = new int[M];//存的是双倍,所以是Mstatic boolean[] st = new boolean[N];static int ans = N; //一开始将最大值赋值成N,最大了/**** 邻接表,存储方法* 邻接表不用管执行顺序,只需要知道每个节点能够执行到每个多少个节点就行* 比如案例中4 3 , 4 6 ,头结点4插入两个节点3和6,所以执行到4就能够执行3和6,* 固定的,邻接表就是这样子的***/public static void add(int a,int b){e[idx] = b;ne[idx] = h[a];h[a] = idx++;}//返回的是当前子树的数量,比如1下面的所有数量包括自己就是9public static int dfs(int u){int res = 0;//连通块中的最大值这个其实就是ans,到时候跟ans比较大小,小的话就赋值给ans的st[u] = true;//将这个删除的点标记,下次不在遍历int sum = 1;//将删除的点也算上是初始值就是1;到时候有利于求n-sum;//单链表遍历for(int i = h[u];i != -1 ; i = ne[i]){int j = e[i];//然后将每一个的指向的点用变量表示出来if(!st[j]){ //然后如果是没用过,没被标记过的,就可以执行int s = dfs(j);//然后递归他的邻接表上面所有能够抵达的点//然后返回的数量是他所删除的点下面的连通块的大小res = Math.max(res,s); //然后和res比较一下大小,谁大谁就是最大连通块sum += s; //这里是将每递归一个点,就增加一个返回的s,就可以将这个值作为返回值成为最大连通块}}/**** 因为邻接表表中只是往下面执行,删除的点的上面的连通块可能是最大的连通块,* 所以需要用总数减去我们下面所统计出来的最大的连通块* 然后将最大的连通块的值赋值给res* **/res = Math.max(res,n-sum); //然后将每个次的最大值进行比较,留下最小的最大值ans = Math.min(res,ans);return sum;}    public static void main(String[] ags){Scanner scan = new Scanner(System.in);n = scan.nextInt();//这里是将每一个头节点都赋值成-1for(int i = 1 ; i < N ; i++ ){h[i] = -1;}//案例输入输出for(int i = 0 ; i < n - 1 ; i ++){int a = scan.nextInt();int b = scan.nextInt();//因为是无向边,所以就两个数同时指向对方add(a,b);add(b,a);}dfs(1);//从1开始//最后输出的是最小的最大值System.out.println(ans);}
}

树与图的广度优先遍历

图中点的层次

思路

最短路径都参考bfs写法,队列引入更新距离矩阵d

代码

import java.util.*;
public class Main{static int N = 100010,M = N * 2,idx,hh,tt,n,m;static int[] h = new int[N];static int[] e = new int[M];//存的是双倍,所以是Mstatic int[] ne = new int[M];//存的是双倍,所以是Mstatic int[] d = new int[M];//1->n的距离//初始化队列static int[] q = new int[N];public static void add(int a,int b){e[idx]=b;ne[idx]=h[a];h[a]=idx++;} public static int bfs(){hh=0;tt=-1;//初始化 放入1号点q[++tt]=1;d[1]=0;while(hh<=tt){int t = q[hh++];for(int i=h[t];i!=-1;i=ne[i]){int j = e[i];if(d[j]==-1){d[j]=d[t]+1;q[++tt]=j;}}}return d[n];}public static void main(String[] ags){Scanner scan = new Scanner(System.in);n = scan.nextInt();m = scan.nextInt();for(int i = 1;i<N;i++){h[i]=-1;d[i]=-1;}while(m-->0){int a = scan.nextInt();int b = scan.nextInt();add(a,b);}System.out.println(bfs());}
}
http://www.dtcms.com/a/611331.html

相关文章:

  • 有个网站可以学做ppt模板第三方网站
  • Python 中的 *args 和 **kwargs
  • 蘑菇街的网站建设如何做网站主赚钱
  • 全国网站直播平台被摧毁wordpress插件免费吗
  • 连锁餐饮行业ERP系统如何选择?
  • 做网站的绿色背景图有什么做木工的网站
  • 专业网网站建设赣州新闻头条
  • idea 启动失败,不加载自己的配置文件
  • 静态网站结构如何更新wordpress变色龙主题
  • 进入职场第五课——突破和跃升
  • SSN和ijtag在scan中的应用与区别
  • 网站设计总结与心得体会flash制作技巧
  • 怎么给网站做懒加载网站开发 非对称加密
  • 零偏压石墨烯探测器赋能《Nature Communications》披露全等离子体太赫兹收发芯片新突破
  • 在百度怎么建立自己的网站网推平台有哪些
  • 做搜狗pc网站点嘉上营销
  • Paimon的merge-engine配置
  • wordpress 站点图标网站源码下载了没有管理后台
  • C语言编译器在Win7系统下的安装与配置
  • 青岛集团网站建设宿州网站建设时间
  • Rust 中的 Tokio 线程同步机制
  • 平台网站建设方案书建设视频网站费用吗
  • 网站关键词字符编辑昌江网站建设
  • CRS税务合规解决方案:马来西亚税号 vs 新加坡自雇EP全面解析(中国卖家税务规划指南)
  • 基于Rust实现高性能数据处理引擎
  • 可以做网站引导页的页面中文域名注册 .网站
  • 问答社区网站建设艺术风格网站
  • 江苏企业建设网站公司网页制作基础教程黄洪杰
  • 做技术网站赚钱吗太原网络广告公司
  • 住房和城乡建设部网站注册山东网站建设最便宜