尚硅谷 java数据结构与算法 学习笔记(三)

多路查找树

在这里插入图片描述在这里插入图片描述

2-3树

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
插入28
在这里插入图片描述
在这里插入图片描述

B树 B+树 B*树

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

快速入门案例

在这里插入图片描述

代码实现

package com.luyi.graph;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author 卢意
 * @create 2020-12-16 19:12
 */
public class Graph {
   
	private ArrayList<String> vertexList; // 存储节点的集合
	private int[][] edges; // 存储对应的邻接矩阵
	private int numberOfEdges; // 表示边的数目

	public static void main(String[] args) {
   
		// 节点的个数
		int n = 5;
		String[] vertexValue = {
   "A", "B", "C", "D", "E"};
		// 创建图对象
		Graph graph = new Graph(n);
		// 循环添加节点数据
		for (String item : vertexValue) {
   
			graph.insertVertex(item);
		}
		// 添加边 A-B A-C B-C B-D B-E
		graph.insertEdge(0, 1, 1);
		graph.insertEdge(0, 2, 1);
		graph.insertEdge(1, 2, 1);
		graph.insertEdge(1, 3, 1);
		graph.insertEdge(1, 3, 1);
		graph.insertEdge(1, 4, 1);

		graph.showGraph();

	}


	public Graph (int n) {
   
		// 初始化矩阵 和 arrayList
		edges = new int[n][n];
		vertexList = new ArrayList<>(n);
		numberOfEdges = 0;
	}

	// 图的常用方法

	// 1 返回节点的个数
	public int getNumberOfVertex() {
   
		return vertexList.size();
	}

	// 2 得到边的数目
	public int getNumberOfEdges() {
   
		return numberOfEdges;
	}

	// 3 返回节点i(下标) 对应的数据 0->"A" 1->"B"
	public String getValueByIndex(int i) {
   
		return vertexList.get(i);
	}
	// 4. 返回v1 和 v2 边的权值
	public int insertVertex(int v1, int v2) {
   
		return edges[v1][v2];
	}

	// 5. 显示图对应的矩阵
	public void showGraph() {
   
		System.out.println("遍历矩阵 ");
		for (int[] k : edges) {
   
			System.out.println(Arrays.toString(k));
		}
	}

	// 插入节点
	public void insertVertex(String vertex) {
   
		vertexList.add(vertex);
	}

	// 添加边

	/**
	 *
	 * @param v1 第一个顶点的下标 第几个顶点
	 * @param v2  第二个顶点的下标
	 * @param weight 边的权值
	 */
	public void insertEdge(int v1, int v2, int weight) {
   
		edges[v1][v2] = weight;
		edges[v2][v1] = weight;
		numberOfEdges++;
	}
}

图的深度优先遍历

在这里插入图片描述
在这里插入图片描述

代码实现

package com.luyi.graph;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author 卢意
 * @create 2020-12-16 19:12
 */
public class Graph {
   
	private ArrayList<String> vertexList; // 存储节点的集合
	private int[][] edges; // 存储对应的邻接矩阵
	private int numberOfEdges; // 表示边的数目
	private boolean[] isVisited; // 记录节点是否被访问

	public static void main(String[] args) {
   
		// 节点的个数
		int n = 5;
		String[] vertexValue = {
   "A", "B", "C", "D", "E"};
		// 创建图对象
		Graph graph = new Graph(n);
		// 循环添加节点数据
		for (String item : vertexValue) {
   
			graph.insertVertex(item);
		}
		// 添加边 A-B A-C B-C B-D B-E
		graph.insertEdge(0, 1, 1);
		graph.insertEdge(0, 2, 1);
		graph.insertEdge(1, 2, 1);
		graph.insertEdge(1, 3, 1);
		graph.insertEdge(1, 3, 1);
		graph.insertEdge(1, 4, 1);

		graph.showGraph();

		System.out.println("深度优先遍历");
		graph.dfs(); // A->B->C->D->E->
	}


	public Graph (int n) {
   
		// 初始化矩阵 和 arrayList
		edges = new int[n][n];
		vertexList = new ArrayList<>(n);
		numberOfEdges = 0;
		isVisited = new boolean[n];
	}

	// 得到第一个邻接结点的下标

	/**
	 * 求该结点的第一个邻接矩阵下标
	 * @param index 该结点的下标
	 * @return 如果存在就返回对应的下标 否则返回-1
 	 */
	public int getFirstNeighbor(int index) {
   
		for (int j = 0; j < vertexList.size(); j++) {
   
			if (edges[index][j] > 0) {
   
				return j;
			}
		}
		return -1;
	}
	// 根据前一个邻接节点的下标 获取下一个邻接节点
	public int getNextNeighbor(int v1, int v2) {
   
		for (int j = v2 + 1; j < vertexList.size(); j++) {
   
			if (edges[v1][j] > 0) {
   
				return j;
			}
		}
		return -1;
	}

	// 深度优先遍历方法
	public void dfs(boolean[] isVisit, int i) {
   
		// 首先访问该节点
		System.out.print(getValueByIndex(i) + "->");
		// 将该节点设置已经访问过
		isVisit[i] = true;
		// 查找下标为i 的邻接节点
		int w = getFirstNeighbor(i);
		while (w != -1) {
   
			if (!isVisit[w]) {
    // 没有被访问过
				dfs(isVisit, w);
			}
			// 如果w 被访问过了 去找 下标为i 的节点的 下一个邻接节点的下一个邻接节点
			w = getNextNeighbor(i, w);
		}
	}

	// 对dfs 进行重载 遍历所有的节点 并进行 dfs
	public void dfs() {
   
		// 回溯遍历dfs
		for(int i = 0; i < vertexList.size(); i++) {
   
			 if (!isVisited[i]) {
   
			 	dfs(isVisited, i);
			 }
		}
	}

	// 图的常用方法

	// 1 返回节点的个数
	public int getNumberOfVertex() {
   
		return vertexList.size();
	}

	// 2 得到边的数目
	public int getNumberOfEdges() {
   
		return numberOfEdges;
	}

	// 3 返回节点i(下标) 对应的数据 0->"A" 1->"B"
	public String getValueByIndex(int i) {
   
		return vertexList.get(i);
	}
	// 4. 返回v1 和 v2 边的权值
	public int insertVertex(int v1, int v2) {
   
		return edges[v1][v2];
	}

	// 5. 显示图对应的矩阵
	public void showGraph() {
   
		System.out.println("遍历矩阵 ");
		for (int[] k : edges) {
   
			System.out.println(Arrays.toString(k));
		}
	}

	// 插入节点
	public void insertVertex(String vertex) {
   
		vertexList.add(vertex);
	}

	// 添加边

	/**
	 *
	 * @param v1 第一个顶点的下标 第几个顶点
	 * @param v2  第二个顶点的下标
	 * @param weight 边的权值
	 */
	public void insertEdge(int v1, int v2, int weight) {
   
		edges[v1][v2] = weight;
		edges[v2][v1] = weight;
		numberOfEdges++;
	}
}

图的广度优先遍历

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码实现

// 对一个结点进行广度优先遍历的方法
	private void bfs(boolean[] isVisited, int i) {
   
		int u; // 表示队列的头结点的下标
		int w; // 邻接节点的下标
		// 队列存放访问过的节点 (现进先出)
		LinkedList<Integer> queue = new LinkedList<Integer>();
		// 访问当前节点
		System.out.print(getValueByIndex(i) + "->");
		// 标记为已访问
		isVisited[i] = true;
		// 将节点加入队列
		queue.addLast(i);
		while (!queue.isEmpty()) {
   
			// 取出对列的头结点坐标
			 u = queue.removeFirst();
			 w = getFirstNeighbor(u);
			 while (w != -1) {
    //
			 	// 是否访问过
				 if (!isVisited[w]) {
   
				 	System.out.print(getValueByIndex(w) + "->");
				 	isVisited[w] = true;
				 	 // 入队列
					 queue.addLast(w);
				 }
				 // 已经访问过的话 以u为为前驱 找 w 的下一个邻接结点
				 w = getNextNeighbor(u, w); // 体现出广度优先
			 }
		}
	}

	// 遍历所有的节点 都进行广度优先搜索
	public void bfs() {
   
		for (int i = 0; i < vertexList.size(); i++) {
   
			if (!isVisited[i]) {
   
				bfs(isVisited, i);
			}
		}
	}

图的深度优先 VS 广度优先

在这里插入图片描述

程序员常用10种算法

二分查找法 非递归

在这里插入图片描述

代码实现

package com.luyi.algorithm;

/**
 * @author 卢意
 * @create 2020-12-17 14:26
 */
public class BinarySearchNoRecursion {
   
	public static void main(String[] args) {
   
		//
		int[] arr = {
   1,3, 8, 10, 11, 67, 100};
		int i = binarySearch(arr, 100);
		System.out.println(i);
	}
	/**
	 * 二分查找的非递归实现
	 * @param arr 带查找的数组  arr 默认是升序排列
	 * @param target 要查找的目标
	 * @return -1 表示没有找到
	 */
	public static int binarySearch(int[] arr, int target) {
   
		int left = 0;
		int right = arr.length - 1;
		while (left <= right) {
   
			int mid = (left + right) / 2;
			if (arr[mid] == target) {
   
				return mid;
			}else if (arr[mid] > target) {
    // 需要向左边查找
				right = mid - 1;
			}else {
    // 需要向右边查找
				left = mid + 1;
			}
		}
		return -1;
	}
}

分治算法

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

分治法解决汉诺塔问题 代码实现

package com.luyi.algorithm;

/**
 * 汉罗塔 移动的方案 分治算法
 * @author 卢意
 * @create 2020-12-17 15:02
 */
public class DACHanoiTower {
   
	public static void main(String[] args) {
   
		hanoiTower(64, 'A', 'B', 'C');
	}

	/**
	 *
	 * @param num 要移动的个数
	 * @param a 起始位置
	 * @param b 中转位置
	 * @param c 目标位置
	 */
	public static void hanoiTower(int num, char a, char b, char c) {
   
		// 如果只有一个盘
		if (num == 1) {
   
			System.out.println("第1个盘从" + a + "->" + c);
		} else {
   
			// 如果我们有n >= 2情况 我们总是可以看做是两个盘 1 最下面的盘 2 上面所有的盘
			// 1 先把上面的盘 a - > b  移动过程暂存到c
			hanoiTower(num- 1, a, c, b
  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 目录 1 Graph 图论 3 | DAG 的深度优先搜索标记 3 | 无向图找桥 3 | 无向图连通度(割) 3 | 最大团问题 DP + DFS 3 | 欧拉路径 O(E) 3 | DIJKSTRA 数组实现 O(N^2) 3 | DIJKSTRA O(E * LOG E) 4 | BELLMANFORD 单源最短路 O(VE) 4 | SPFA(SHORTEST PATH FASTER ALGORITHM) 4 | 第 K 短路(DIJKSTRA) 5 | 第 K 短路(A*) 5 | PRIM 求 MST 6 | 次小生成树 O(V^2) 6 | 最小生成森林问题(K 颗树)O(MLOGM). 6 | 有向图最小树形图 6 | MINIMAL STEINER TREE 6 | TARJAN 强连通分量 7 | 弦图判断 7 | 弦图的 PERFECT ELIMINATION 点排列 7 | 稳定婚姻问题 O(N^2) 7 | 拓扑排序 8 | 无向图连通分支(DFS/BFS 邻接阵) 8 | 有向图强连通分支(DFS/BFS 邻接阵)O(N^2) 8 | 有向图最小点基(邻接阵)O(N^2) 9 | FLOYD 求最小环 9 | 2-SAT 问题 9 Network 网络流 11 | 二分图匹配(匈牙利算法 DFS 实现) 11 | 二分图匹配(匈牙利算法 BFS 实现) 11 | 二分图匹配(HOPCROFT-CARP 的算法) 11 | 二分图最佳匹配(KUHN MUNKRAS 算法 O(M*M*N)) 11 | 无向图最小割 O(N^3) 12 | 有上下界的最小(最大)流 12 | DINIC 最大流 O(V^2 * E) 12 | HLPP 最大流 O(V^3) 13 | 最小费用流 O(V * E * F) 13 | 最小费用流 O(V^2 * F) 14 | 最佳边割集 15 | 最佳点割集 15 | 最小边割集 15 | 最小点割集(点连通度) 16 | 最小路径覆盖 O(N^3) 16 | 最小点集覆盖 16 Structure 数据结构 17 | 求某天是星期几 17 | 左偏树 合并复杂度 O(LOG N) 17 | 树状数组 17 | 二维树状数组 17 | TRIE 树(K 叉) 17 | TRIE 树(左儿子又兄弟) 18 | 后缀数组 O(N * LOG N) 18 | 后缀数组 O(N) 18 | RMQ 离线算法 O(N*LOGN)+O(1) 19 | RMQ(RANGE MINIMUM/MAXIMUM QUERY)-ST 算法 (O(NLOGN + Q)) 19 | RMQ 离线算法 O(N*LOGN)+O(1)求解 LCA 19 | LCA 离线算法 O(E)+O(1) 20 | 带权值的并查集 20 | 快速排序 20 | 2 台机器工作调度 20 | 比较高效的大数 20 | 普通的大数运算 21 | 最长公共递增子序列 O(N^2) 22 | 0-1 分数规划 22 | 最长有序子序列(递增/递减/非递增/非递减) 22 | 最长公共子序列 23 | 最少找硬币问题(贪心策略-深搜实现) 23 | 棋盘分割 23 | 汉诺塔 23 | STL 中的 PRIORITY_QUEUE 24 | 堆栈 24 | 区间最大频率 24 | 取第 K 个元素 25 | 归并排序求逆序数 25 | 逆序数推排列数 25 | 二分查找 25 | 二分查找(大于等于 V 的第一个值) 25 | 所有数位相加 25 Number 数论 26 1 |递推求欧拉函数 PHI(I) 26 |单独求欧拉函数 PHI(X) 26 | GCD 最大公约数 26 | 快速 GCD 26 | 扩展 GCD 26 | 模线性方程 A * X = B (% N) 26 | 模线性方程组 26 | 筛素数 [1..N] 26 | 高效求小范围素数 [1..N] 26 | 随机素数测试(伪素数原理) 26 | 组合数学相关 26 | POLYA 计数 27 | 组合数 C(N, R) 27 | 最大 1 矩阵 27 | 约瑟夫环问题(数学方法) 27 | 约瑟夫环问题(数组模拟) 27 | 取石子游戏 1 27 | 集合划分问题 27 | 大数平方根(字符串数组表示) 28 | 大数取模的二进制方法 28 | 线性方程组 A[][]X[]=B[] 28 | 追赶法解周期性方程 28 | 阶乘最后非零位,复杂度 O(NLOGN) 29 递归方法求解排列组合问题 30 | 类循环排列 30 | 全排列 30 | 不重复排列 30 | 全组合 31 | 不重复组合 31 | 应用 31 模式串匹配问题总结 32 | 字符串 HASH 32 | KMP 匹配算法 O(M+N) 32 | KARP-RABIN 字符串匹配 32 | 基于 KARP-RABIN 的字符块匹配 32 | 函数名: STRSTR 32 | BM 算法的改进的算法 SUNDAY ALGORITHM 32 | 最短公共祖先(两个长字符串) 33 | 最短公共祖先(多个短字符串) 33 Geometry 计算几何 34 | GRAHAM 求凸包 O(N * LOGN) 34 | 判断线段相交 34 | 求多边形重心 34 | 角形几个重要的点 34 | 平面最近点对 O(N * LOGN) 34 | LIUCTIC 的计算几何库 35 | 求平面上两点之间的距离 35 | (P1-P0)*(P2-P0)的叉积 35 | 确定两条线段是否相交 35 | 判断点 P 是否在线段 L 上 35 | 判断两个点是否相等 35 | 线段相交判断函数 35 | 判断点 Q 是否在多边形内 35 | 计算多边形的面积 35 | 解二次方程 AX^2+BX+C=0 36 | 计算直线的一般式 AX+BY+C=0 36 | 点到直线距离 36 | 直线与圆的交点,已知直线与圆相交 36 | 点是否在射线的正向 36 | 射线与圆的第一个交点 36 | 求点 P1 关于直线 LN 的对称点 P2 36 | 两直线夹角(弧度) 36 ACM/ICPC 竞赛之 STL 37 ACM/ICPC 竞赛之 STL 简介 37 ACM/ICPC 竞赛之 STL--PAIR 37 ACM/ICPC 竞赛之 STL--VECTOR 37 ACM/ICPC 竞赛之 STL--ITERATOR 简介 38 ACM/ICPC 竞赛之 STL--STRING 38 ACM/ICPC 竞赛之 STL--STACK/QUEUE 38 ACM/ICPC 竞赛之 STL--MAP 40 ACM/ICPC 竞赛之 STL--ALGORITHM 40 STL IN ACM 41 头文件 42 线段树 43 求矩形并的面积(线段树+离散化+扫描线) 43 求矩形并的周长(线段树+离散化+扫描线) 44

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值