数据结构之程序员常用10种算法

}

System.out.println(“============================”);

//输出最后我们是放入的哪些商品

//遍历path, 这样输出会把所有的放入情况都得到, 其实我们只需要最后的放入

// for(int i = 0; i < path.length; i++) {

// for(int j=0; j < path[i].length; j++) {

// if(path[i][j] == 1) {

// System.out.printf(“第%d个商品放入到背包\n”, i);

// }

// }

// }

//动脑筋

int i = path.length - 1; //行的最大下标

int j = path[0].length - 1; //列的最大下标

while(i > 0 && j > 0 ) { //从path的最后开始找

if(path[i][j] == 1) {

System.out.printf(“第%d个商品放入到背包\n”, i);

j -= w[i-1]; //w[i-1]

}

i–;

}

}

}

四、KMP算法


1.字符串匹配问题

在这里插入图片描述

2.暴力匹配算法

在这里插入图片描述

package com.atguigu.kmp;

public class ViolenceMatch {

public static void main(String[] args) {

// TODO Auto-generated method stub

//测试暴力匹配算法

String str1 = “硅硅谷 尚硅谷你尚硅 尚硅谷你尚硅谷你尚硅你好”;

String str2 = “尚硅谷你尚硅你~”;

int index = violenceMatch(str1, str2);

System.out.println(“index=” + index);

}

// 暴力匹配算法实现

public static int violenceMatch(String str1, String str2) {

char[] s1 = str1.toCharArray();

char[] s2 = str2.toCharArray();

int s1Len = s1.length;

int s2Len = s2.length;

int i = 0; // i索引指向s1

int j = 0; // j索引指向s2

while (i < s1Len && j < s2Len) {// 保证匹配时,不越界

if(s1[i] == s2[j]) {//匹配ok

i++;

j++;

} else { //没有匹配成功

//如果失配(即str1[i]! = str2[j]),令i = i - (j - 1),j = 0。

i = i - (j - 1);

j = 0;

}

}

//判断是否匹配成功

if(j == s2Len) {

return i - j;

} else {

return -1;

}

}

}

3.KMP算法介绍

在这里插入图片描述

4.KMP算法解决字符串匹配问题

在这里插入图片描述

package com.atguigu.kmp;

import java.util.Arrays;

public class KMPAlgorithm {

public static void main(String[] args) {

// TODO Auto-generated method stub

String str1 = “BBC ABCDAB ABCDABCDABDE”;

String str2 = “ABCDABD”;

//String str2 = “BBC”;

int[] next = kmpNext(“ABCDABD”); //[0, 1, 2, 0]

System.out.println(“next=” + Arrays.toString(next));

int index = kmpSearch(str1, str2, next);

System.out.println(“index=” + index); // 15了

}

//写出我们的kmp搜索算法

/**

  • @param str1 源字符串

  • @param str2 子串

  • @param next 部分匹配表, 是子串对应的部分匹配表

  • @return 如果是-1就是没有匹配到,否则返回第一个匹配的位置

*/

public static int kmpSearch(String str1, String str2, int[] next) {

//遍历

for(int i = 0, j = 0; i < str1.length(); i++) {

//需要处理 str1.charAt(i) != str2.charAt(j), 去调整j的大小

//KMP算法核心点, 可以验证…

while( j > 0 && str1.charAt(i) != str2.charAt(j)) {

j = next[j-1];

}

if(str1.charAt(i) == str2.charAt(j)) {

j++;

}

if(j == str2.length()) {//找到了 // j = 3 i

return i - j + 1;

}

}

return -1;

}

//获取到一个字符串(子串) 的部分匹配值表

public static int[] kmpNext(String dest) {

//创建一个next 数组保存部分匹配值

int[] next = new int[dest.length()];

next[0] = 0; //如果字符串是长度为1 部分匹配值就是0

for(int i = 1, j = 0; i < dest.length(); i++) {

//当dest.charAt(i) != dest.charAt(j) ,我们需要从next[j-1]获取新的j

//直到我们发现 有 dest.charAt(i) == dest.charAt(j)成立才退出

//这时kmp算法的核心点

while(j > 0 && dest.charAt(i) != dest.charAt(j)) {

j = next[j-1];

}

//当dest.charAt(i) == dest.charAt(j) 满足时,部分匹配值就是+1

if(dest.charAt(i) == dest.charAt(j)) {

j++;

}

next[i] = j;

}

return next;

}

}

五、贪心算法


1.集合覆盖问题

在这里插入图片描述

2.介绍

在这里插入图片描述

3.应用

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

package com.atguigu.greedy;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.HashSet;

public class GreedyAlgorithm {

public static void main(String[] args) {

//创建广播电台,放入到Map

HashMap<String,HashSet> broadcasts = new HashMap<String, HashSet>();

//将各个电台放入到broadcasts

HashSet hashSet1 = new HashSet();

hashSet1.add(“北京”);

hashSet1.add(“上海”);

hashSet1.add(“天津”);

HashSet hashSet2 = new HashSet();

hashSet2.add(“广州”);

hashSet2.add(“北京”);

hashSet2.add(“深圳”);

HashSet hashSet3 = new HashSet();

hashSet3.add(“成都”);

hashSet3.add(“上海”);

hashSet3.add(“杭州”);

HashSet hashSet4 = new HashSet();

hashSet4.add(“上海”);

hashSet4.add(“天津”);

HashSet hashSet5 = new HashSet();

hashSet5.add(“杭州”);

hashSet5.add(“大连”);

//加入到map

broadcasts.put(“K1”, hashSet1);

broadcasts.put(“K2”, hashSet2);

broadcasts.put(“K3”, hashSet3);

broadcasts.put(“K4”, hashSet4);

broadcasts.put(“K5”, hashSet5);

//allAreas 存放所有的地区

HashSet allAreas = new HashSet();

allAreas.add(“北京”);

allAreas.add(“上海”);

allAreas.add(“天津”);

allAreas.add(“广州”);

allAreas.add(“深圳”);

allAreas.add(“成都”);

allAreas.add(“杭州”);

allAreas.add(“大连”);

//创建ArrayList, 存放选择的电台集合

ArrayList selects = new ArrayList();

//定义一个临时的集合, 在遍历的过程中,存放遍历过程中的电台覆盖的地区和当前还没有覆盖的地区的交集

HashSet tempSet = new HashSet();

//定义给maxKey , 保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key

//如果maxKey 不为null , 则会加入到 selects

String maxKey = null;

while(allAreas.size() != 0) { // 如果allAreas 不为0, 则表示还没有覆盖到所有的地区

//每进行一次while,需要

maxKey = null;

//遍历 broadcasts, 取出对应key

for(String key : broadcasts.keySet()) {

//每进行一次for

tempSet.clear();

//当前这个key能够覆盖的地区

HashSet areas = broadcasts.get(key);

tempSet.addAll(areas);

//求出tempSet 和 allAreas 集合的交集, 交集会赋给 tempSet

tempSet.retainAll(allAreas);

//如果当前这个集合包含的未覆盖地区的数量,比maxKey指向的集合地区还多

//就需要重置maxKey

// tempSet.size() >broadcasts.get(maxKey).size()) 体现出贪心算法的特点,每次都选择最优的

if(tempSet.size() > 0 &&

(maxKey == null || tempSet.size() >broadcasts.get(maxKey).size())){

maxKey = key;

}

}

//maxKey != null, 就应该将maxKey 加入selects

if(maxKey != null) {

selects.add(maxKey);

//将maxKey指向的广播电台覆盖的地区,从 allAreas 去掉

allAreas.removeAll(broadcasts.get(maxKey));

}

}

System.out.println(“得到的选择结果是” + selects);//[K1,K2,K3,K5]

}

}

4.贪心算法注意事项和细节

在这里插入图片描述

六、普里姆算法


1.修路问题

在这里插入图片描述

2.最小生成树

在这里插入图片描述

3.算法介绍

在这里插入图片描述

4.实践

在这里插入图片描述

package com.atguigu.prim;

import java.util.Arrays;

public class PrimAlgorithm {

public static void main(String[] args) {

//测试看看图是否创建ok

char[] data = new char[]{‘A’,‘B’,‘C’,‘D’,‘E’,‘F’,‘G’};

int verxs = data.length;

//邻接矩阵的关系使用二维数组表示,10000这个大数,表示两个点不联通

int [][]weight=new int[][]{

{10000,5,7,10000,10000,10000,2},

{5,10000,10000,9,10000,10000,3},

{7,10000,10000,10000,8,10000,10000},

{10000,9,10000,10000,10000,4,10000},

{10000,10000,8,10000,10000,5,4},

{10000,10000,10000,4,5,10000,6},

{2,3,10000,10000,4,6,10000},};

//创建MGraph对象

MGraph graph = new MGraph(verxs);

//创建一个MinTree对象

MinTree minTree = new MinTree();

minTree.createGraph(graph, verxs, data, weight);

//输出

minTree.showGraph(graph);

//测试普利姆算法

minTree.prim(graph, 1);//

}

}

//创建最小生成树->村庄的图

class MinTree {

//创建图的邻接矩阵

/**

  • @param graph 图对象

  • @param verxs 图对应的顶点个数

  • @param data 图的各个顶点的值

  • @param weight 图的邻接矩阵

*/

public void createGraph(MGraph graph, int verxs, char data[], int[][] weight) {

int i, j;

for(i = 0; i < verxs; i++) {//顶点

graph.data[i] = data[i];

for(j = 0; j < verxs; j++) {

graph.weight[i][j] = weight[i][j];

}

}

}

//显示图的邻接矩阵

public void showGraph(MGraph graph) {

for(int[] link: graph.weight) {

System.out.println(Arrays.toString(link));

}

}

//编写prim算法,得到最小生成树

/**

  • @param graph 图

  • @param v 表示从图的第几个顶点开始生成’A’->0 ‘B’->1…

*/

public void prim(MGraph graph, int v) {

//visited[] 标记结点(顶点)是否被访问过

int visited[] = new int[graph.verxs];

//visited[] 默认元素的值都是0, 表示没有访问过

// for(int i =0; i <graph.verxs; i++) {

// visited[i] = 0;

// }

//把当前这个结点标记为已访问

visited[v] = 1;

//h1 和 h2 记录两个顶点的下标

int h1 = -1;

int h2 = -1;

int minWeight = 10000; //将 minWeight 初始成一个大数,后面在遍历过程中,会被替换

for(int k = 1; k < graph.verxs; k++) {//因为有 graph.verxs顶点,普利姆算法结束后,有 graph.verxs-1边

//这个是确定每一次生成的子图 ,和哪个结点的距离最近

for(int i = 0; i < graph.verxs; i++) {// i结点表示被访问过的结点

for(int j = 0; j< graph.verxs;j++) {//j结点表示还没有访问过的结点

if(visited[i] == 1 && visited[j] == 0 && graph.weight[i][j] < minWeight) {

//替换minWeight(寻找已经访问过的结点和未访问过的结点间的权值最小的边)

minWeight = graph.weight[i][j];

h1 = i;

h2 = j;

}

}

}

//找到一条边是最小

System.out.println(“边<” + graph.data[h1] + “,” + graph.data[h2] + “> 权值:” + minWeight);

//将当前这个结点标记为已经访问

visited[h2] = 1;

//minWeight 重新设置为最大值 10000

minWeight = 10000;

}

}

}

class MGraph {

int verxs; //表示图的节点个数

char[] data;//存放结点数据

int[][] weight; //存放边,就是我们的邻接矩阵

public MGraph(int verxs) {

this.verxs = verxs;

data = new char[verxs];

weight = new int[verxs][verxs];

}

}

七、克鲁斯卡尔算法


1.公交站问题

在这里插入图片描述

2.算法介绍

在这里插入图片描述

3.实践

package com.atguigu.kruskal;

import java.util.Arrays;

public class KruskalCase {

private int edgeNum; //边的个数

private char[] vertexs; //顶点数组

private int[][] matrix; //邻接矩阵

//使用 INF 表示两个顶点不能连通

private static final int INF = Integer.MAX_VALUE;

public static void main(String[] args) {

char[] vertexs = {‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’};

//克鲁斯卡尔算法的邻接矩阵

int matrix[][] = {

/A//B//C//D//E//F//G/

/A/ { 0, 12, INF, INF, INF, 16, 14},

/B/ { 12, 0, 10, INF, INF, 7, INF},

/C/ { INF, 10, 0, 3, 5, 6, INF},

/D/ { INF, INF, 3, 0, 4, INF, INF},

/E/ { INF, INF, 5, 4, 0, 2, 8},

/F/ { 16, 7, 6, INF, 2, 0, 9},

/G/ { 14, INF, INF, INF, 8, 9, 0}};

//大家可以在去测试其它的邻接矩阵,结果都可以得到最小生成树.

//创建KruskalCase 对象实例

KruskalCase kruskalCase = new KruskalCase(vertexs, matrix);

//输出构建的

kruskalCase.print();

kruskalCase.kruskal();

}

//构造器

public KruskalCase(char[] vertexs, int[][] matrix) {

//初始化顶点数和边的个数

int vlen = vertexs.length;

//初始化顶点, 复制拷贝的方式

this.vertexs = new char[vlen];

for(int i = 0; i < vertexs.length; i++) {

this.vertexs[i] = vertexs[i];

}

//初始化边, 使用的是复制拷贝的方式

this.matrix = new int[vlen][vlen];

for(int i = 0; i < vlen; i++) {

for(int j= 0; j < vlen; j++) {

this.matrix[i][j] = matrix[i][j];

}

}

//统计边的条数

for(int i =0; i < vlen; i++) {

for(int j = i+1; j < vlen; j++) {

if(this.matrix[i][j] != INF) {

edgeNum++;

}

}

}

}

public void kruskal() {

int index = 0; //表示最后结果数组的索引

int[] ends = new int[edgeNum]; //用于保存"已有最小生成树" 中的每个顶点在最小生成树中的终点

//创建结果数组, 保存最后的最小生成树

EData[] rets = new EData[edgeNum];

//获取图中 所有的边的集合 , 一共有12边

EData[] edges = getEdges();

System.out.println(“图的边的集合=” + Arrays.toString(edges) + " 共"+ edges.length); //12

//按照边的权值大小进行排序(从小到大)

sortEdges(edges);

//遍历edges 数组,将边添加到最小生成树中时,判断是准备加入的边否形成了回路,如果没有,就加入 rets, 否则不能加入

for(int i=0; i < edgeNum; i++) {

//获取到第i条边的第一个顶点(起点)

int p1 = getPosition(edges[i].start); //p1=4

//获取到第i条边的第2个顶点

int p2 = getPosition(edges[i].end); //p2 = 5

//获取p1这个顶点在已有最小生成树中的终点

int m = getEnd(ends, p1); //m = 4

//获取p2这个顶点在已有最小生成树中的终点

int n = getEnd(ends, p2); // n = 5

//是否构成回路

if(m != n) { //没有构成回路

ends[m] = n; // 设置m 在"已有最小生成树"中的终点 <E,F> [0,0,0,0,5,0,0,0,0,0,0,0]

rets[index++] = edges[i]; //有一条边加入到rets数组

}

}

//<E,F> <C,D> <D,E> <B,F> <E,G> <A,B>。

//统计并打印 “最小生成树”, 输出 rets

System.out.println(“最小生成树为”);

for(int i = 0; i < index; i++) {

System.out.println(rets[i]);

}

}

//打印邻接矩阵

public void print() {

System.out.println(“邻接矩阵为: \n”);

for(int i = 0; i < vertexs.length; i++) {

for(int j=0; j < vertexs.length; j++) {

System.out.printf(“%12d”, matrix[i][j]);

}

System.out.println();//换行

}

}

/**

  • 功能:对边进行排序处理, 冒泡排序

  • @param edges 边的集合

*/

private void sortEdges(EData[] edges) {

for(int i = 0; i < edges.length - 1; i++) {

for(int j = 0; j < edges.length - 1 - i; j++) {

if(edges[j].weight > edges[j+1].weight) {//交换

EData tmp = edges[j];

edges[j] = edges[j+1];

edges[j+1] = tmp;

}

}

}

}

/**

  • @param ch 顶点的值,比如’A’,‘B’

  • @return 返回ch顶点对应的下标,如果找不到,返回-1

*/

private int getPosition(char ch) {

for(int i = 0; i < vertexs.length; i++) {

if(vertexs[i] == ch) {//找到

return i;

}

}

//找不到,返回-1

return -1;

}

/**

  • 功能: 获取图中边,放到EData[] 数组中,后面我们需要遍历该数组

  • 是通过matrix 邻接矩阵来获取

  • EData[] 形式 [[‘A’,‘B’, 12], [‘B’,‘F’,7], …]

  • @return

*/

private EData[] getEdges() {

int index = 0;

EData[] edges = new EData[edgeNum];

for(int i = 0; i < vertexs.length; i++) {

for(int j=i+1; j <vertexs.length; j++) {

if(matrix[i][j] != INF) {

edges[index++] = new EData(vertexs[i], vertexs[j], matrix[i][j]);

}

}

}

return edges;

}

/**

  • 功能: 获取下标为i的顶点的终点(), 用于后面判断两个顶点的终点是否相同

  • @param ends : 数组就是记录了各个顶点对应的终点是哪个,ends 数组是在遍历过程中,逐步形成

  • @param i : 表示传入的顶点对应的下标

  • @return 返回的就是 下标为i的这个顶点对应的终点的下标, 一会回头还有来理解

*/

private int getEnd(int[] ends, int i) { // i = 4 [0,0,0,0,5,0,0,0,0,0,0,0]

while(ends[i] != 0) {

i = ends[i];

}

return i;

}

}

//创建一个类EData ,它的对象实例就表示一条边

class EData {

char start; //边的一个点

char end; //边的另外一个点

int weight; //边的权值

//构造器

public EData(char start, char end, int weight) {

this.start = start;

this.end = end;

this.weight = weight;

}

//重写toString, 便于输出边信息

@Override

public String toString() {

return “EData [<” + start + ", " + end + ">= " + weight + “]”;

}

}

八、迪杰斯特拉算法


1.最短路径问题

在这里插入图片描述

2.算法介绍

在这里插入图片描述

3.算法过程

在这里插入图片描述

4.应用

package com.atguigu.dijkstra;

import java.util.Arrays;

public class DijkstraAlgorithm {

public static void main(String[] args) {

char[] vertex = { ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’ };

//邻接矩阵

int[][] matrix = new int[vertex.length][vertex.length];

final int N = 65535;// 表示不可以连接

matrix[0]=new int[]{N,5,7,N,N,N,2};

matrix[1]=new int[]{5,N,N,9,N,N,3};

matrix[2]=new int[]{7,N,N,N,8,N,N};

matrix[3]=new int[]{N,9,N,N,N,4,N};

matrix[4]=new int[]{N,N,8,N,N,5,4};

matrix[5]=new int[]{N,N,N,4,5,N,6};

matrix[6]=new int[]{2,3,N,N,4,6,N};

//创建 Graph对象

Graph graph = new Graph(vertex, matrix);

//测试, 看看图的邻接矩阵是否ok

graph.showGraph();

//测试迪杰斯特拉算法

graph.dsj(2);//C

graph.showDijkstra();

}

}

class Graph {

private char[] vertex; // 顶点数组

private int[][] matrix; // 邻接矩阵

private VisitedVertex vv; //已经访问的顶点的集合

// 构造器

public Graph(char[] vertex, int[][] matrix) {

this.vertex = vertex;

this.matrix = matrix;

}

//显示结果

public void showDijkstra() {

vv.show();

}

// 显示图

public void showGraph() {

for (int[] link : matrix) {

System.out.println(Arrays.toString(link));

}

}

//迪杰斯特拉算法实现

/**

  • @param index 表示出发顶点对应的下标

*/

public void dsj(int index) {

vv = new VisitedVertex(vertex.length, index);

update(index);//更新index顶点到周围顶点的距离和前驱顶点

for(int j = 1; j <vertex.length; j++) {

index = vv.updateArr();// 选择并返回新的访问顶点

update(index); // 更新index顶点到周围顶点的距离和前驱顶点

}

}

//更新index下标顶点到周围顶点的距离和周围顶点的前驱顶点,

private void update(int index) {

int len = 0;

//根据遍历我们的邻接矩阵的 matrix[index]行

for(int j = 0; j < matrix[index].length; j++) {

// len 含义是 : 出发顶点到index顶点的距离 + 从index顶点到j顶点的距离的和

len = vv.getDis(index) + matrix[index][j];

// 如果j顶点没有被访问过,并且 len 小于出发顶点到j顶点的距离,就需要更新

if(!vv.in(j) && len < vv.getDis(j)) {

vv.updatePre(j, index); //更新j顶点的前驱为index顶点

vv.updateDis(j, len); //更新出发顶点到j顶点的距离

}

}

}

}

// 已访问顶点集合

class VisitedVertex {

// 记录各个顶点是否访问过 1表示访问过,0未访问,会动态更新

public int[] already_arr;

// 每个下标对应的值为前一个顶点下标, 会动态更新

public int[] pre_visited;

// 记录出发顶点到其他所有顶点的距离,比如G为出发顶点,就会记录G到其它顶点的距离,会动态更新,求的最短距离就会存放到dis

public int[] dis;

//构造器

/**

  • @param length :表示顶点的个数

  • @param index: 出发顶点对应的下标, 比如G顶点,下标就是6

*/

public VisitedVertex(int length, int index) {

this.already_arr = new int[length];

this.pre_visited = new int[length];

this.dis = new int[length];

//初始化 dis数组

Arrays.fill(dis, 65535);

this.already_arr[index] = 1; //设置出发顶点被访问过

this.dis[index] = 0;//设置出发顶点的访问距离为0

}

/**

  • 功能: 判断index顶点是否被访问过

  • @param index

  • @return 如果访问过,就返回true, 否则访问false

*/

public boolean in(int index) {

return already_arr[index] == 1;

}

/**

  • 功能: 更新出发顶点到index顶点的距离

  • @param index

  • @param len

*/

public void updateDis(int index, int len) {

dis[index] = len;

}

/**

  • 功能: 更新pre这个顶点的前驱顶点为index顶点

  • @param pre

  • @param index

*/

public void updatePre(int pre, int index) {

pre_visited[pre] = index;

}

/**

  • 功能:返回出发顶点到index顶点的距离

  • @param index

*/

public int getDis(int index) {

return dis[index];

}

/**

  • 继续选择并返回新的访问顶点, 比如这里的G 完后,就是 A点作为新的访问顶点(注意不是出发顶点)

  • @return

*/

public int updateArr() {

int min = 65535, index = 0;

for(int i = 0; i < already_arr.length; i++) {

if(already_arr[i] == 0 && dis[i] < min ) {

min = dis[i];

index = i;

}

}

//更新 index 顶点被访问过

already_arr[index] = 1;

return index;

}

//显示最后的结果

//即将三个数组的情况输出

public void show() {

System.out.println(“==========================”);

//输出already_arr

for(int i : already_arr) {

System.out.print(i + " ");

}

System.out.println();

//输出pre_visited

for(int i : pre_visited) {

System.out.print(i + " ");

}

System.out.println();

//输出dis

for(int i : dis) {

System.out.print(i + " ");

}

System.out.println();

//为了好看最后的最短距离,我们处理

char[] vertex = { ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’ };

int count = 0;

for (int i : dis) {

if (i != 65535) {

System.out.print(vertex[count] + “(”+i+") ");

} else {

System.out.println("N ");

}

count++;

}

System.out.println();

}

}

九、弗洛伊德算法


1.算法介绍

在这里插入图片描述

2.算法分析

在这里插入图片描述

3.应用

在这里插入图片描述

package com.atguigu.floyd;

import java.util.Arrays;

public class FloydAlgorithm {

public static void main(String[] args) {

// 测试看看图是否创建成功

char[] vertex = { ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’ };

//创建邻接矩阵

int[][] matrix = new int[vertex.length][vertex.length];
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

针对以上面试题,小编已经把面试题+答案整理好了

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

面试专题

image

除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习

image

image

image
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
ext_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW90YWkxMjM0,size_16,color_FFFFFF,t_70#pic_center)

3.应用

在这里插入图片描述

package com.atguigu.floyd;

import java.util.Arrays;

public class FloydAlgorithm {

public static void main(String[] args) {

// 测试看看图是否创建成功

char[] vertex = { ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’ };

//创建邻接矩阵

int[][] matrix = new int[vertex.length][vertex.length];
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-AdezhahY-1713714141762)]

[外链图片转存中…(img-kNeJ4unx-1713714141763)]

[外链图片转存中…(img-Z4KQrjAt-1713714141763)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

针对以上面试题,小编已经把面试题+答案整理好了

[外链图片转存中…(img-wnJcOaXY-1713714141764)]

[外链图片转存中…(img-Az6P74ez-1713714141764)]

[外链图片转存中…(img-Kff7P1g7-1713714141764)]

面试专题

[外链图片转存中…(img-A07hcAI3-1713714141764)]

除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习

[外链图片转存中…(img-x5zUpg2t-1713714141765)]

[外链图片转存中…(img-3EScxZ0j-1713714141765)]

[外链图片转存中…(img-Rl2k9cfD-1713714141765)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 25
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值