DataStructure
lankerens
lankerens
日常抄代码并给大佬点赞
展开
-
01背包
动态规划 – 01 背包背包问题: 就是给定一个一定容量的背包,一些具有重量和价值的物品,使用这些物品来使得背包所能装的物品价值达到最大01 背包: 物品不能重复放入背包,只能放一次完全背包: 同一个物品可以重复放入多次重点:画图上一行的解影响下一行的解public class Backpack { public static void main(String[] args) { // 记录物品重量 int[] w = {1, 4, .原创 2020-08-02 18:02:26 · 97 阅读 · 0 评论 -
分治算法[汉诺塔问题]
汉诺塔问题 – 分治算法的最佳实践public class Hannuota { public static void main(String[] args) { hannuota(2, 'A', 'B', 'C'); } /** * 汉诺塔问题 * 从 A 移动到 C * @param num 需要移动几个盘子 * @param a A 杠 * @param b B 杠 .原创 2020-08-02 15:01:46 · 216 阅读 · 0 评论 -
二分查找[非递归方式]
二分查找[ 非递归方式 ]思路:传入数组arr 、需要查找的值 target初始化 左边界 left 、右边界 right计算出 mid 值分情况判断,循环条件 left <= right : 左边界小于等于右边界即还没有结束4.1 arr[mid] == target4.2 arr[mid] > target4.3 arr[mid] < target重新计算 mid 值public class BinarySearchNoRecur { pub.原创 2020-08-02 11:18:42 · 192 阅读 · 0 评论 -
图的遍历[DFS、BFS]
图的遍历思路:0. 用邻接矩阵的形式表示图0.1 所在行数,返回第一个邻接点 [重要]0.2 在该行数,继续寻找下一个邻接点返回 [重要]0.3 定义需要使用到的变量 : boolean[] isVisit ; 记录该顶点是否被访问过深度优先遍历 [dfs]1.1 传入 isVisit 数组、当前所遍历的行 i1.2 需要递归1.3 输出当前顶点(该行==一个顶点),标记为已经访问过,然后在 该行 i 寻找第一个邻接点1.4 判断第一个邻接点是否访问过1.4.1 访问过: .原创 2020-08-01 23:02:48 · 185 阅读 · 0 评论 -
图的创建
图的创建定义需要使用到的变量: List<String> 存放顶点、int[][] 存放边、记录边数 edgeNums插入顶点插入边返回对应下边的顶点值获取边数获取边的权值public class Graph { // 存放顶点 private List<String> vertexList ; // 存放边 private int[][] edges ; // 边的数目 private int edgesN.原创 2020-08-01 16:04:41 · 189 阅读 · 0 评论 -
AVL二叉平衡树
AVL二叉平衡树说明: AVL二叉平衡树是对二叉排序树的一种调整,当 7 为根节点,6、5、4、3、2 时,所有节点位于左子节点上,导致相当于一条链表, 增删无问题,可是查询的效率甚至还要比链表差[ 因为还需要额外的判断右子树等操作 ]前提: 是一颗二叉排序树特点: 它是一颗空树 或者 它的节点的左子树和右子树的高度差绝对值不超过 1思路:0. 每添加一次节点,调整一次树左旋转1.1 左子树高度 - 右子树高度 > 11.2 用当前节点值创建出一个新节点 newNode1..原创 2020-07-31 22:25:12 · 211 阅读 · 0 评论 -
二叉排序树
二叉排序树思路:二叉排序树的添加1.1 将第一个添加的作为根节点了1.2 比当前遍历的节点小的 添加到 左边1.3 比当前遍历的节点大的 添加到 右边1.4 尽量不添加相同值得到二叉排序树中,可以在添加的时候 if else 到默认右边二叉排序树的遍历2.1 中序遍历 : 从小到大二叉排序树的删除3.1 删除分三种情况; 1. 删除叶子节点(没有左右子节点)2. 删除带有一个子节点的 3. 删除带有两个子节点的3.2 准备3.2.1 查找需要被删除的节点的方法3.2.2 查找.原创 2020-07-31 17:30:20 · 220 阅读 · 0 评论 -
哈夫曼编码文件压缩解压
哈夫曼编码文件压缩解压没整懂这份代码竟然只能压缩文本文件,内容不能包含中文,不能解压大于 8 k 的 public static void main(String[] args) { // 只能压缩txt,压缩的文件不能有中文 String srcFile = "F:\\Temp\\test2.txt"; String dstFile = "F:\\Temp\\hufmanTxt.zip"; FileZip(srcFil.原创 2020-07-30 19:26:24 · 1201 阅读 · 0 评论 -
哈夫曼编码解码
哈夫曼编码解码zip将 String 的原始字节数组转换成哈夫曼编码处理后的字节数组通过 哈夫曼编码表 获取 byte 对应的 value步长为 8 对StringBuffer进行分割,最后一位不满8位则直接存储通过 Integer.parseInt( , 2) 进行转换byteToBinaryString通过传入 byte 字节 和 是否为 最后一位 flagtemp |= 256 补高位decode哈夫曼解码传入 哈夫曼编码处理后的 字节数组、哈夫曼编码表原始字节数.原创 2020-07-30 15:02:29 · 810 阅读 · 1 评论 -
哈夫曼编码
哈夫曼编码思路:将字符串转为 byte 数组,统计各个字母的个数作为哈夫曼树节点的权值,并加入到 List<hufNode> 中,方便操作通过 List<hufNode> 创建哈夫曼树2.1 List 排序2.2 找出最小的两个值2.3 创建局部二叉树,建立left、right联系,删除原有的两个值,添加新的根节点。获取哈夫曼编码:3.1 定义需要使用到的相关变量3.1.1 StringBuffer context 用来拼接树的路径: 规则:左子节点 0 ,右子.原创 2020-07-29 20:52:04 · 244 阅读 · 0 评论 -
创建哈夫曼树
哈夫曼树该树的带权路径长度(WPL)最小,这样的二叉树叫最优二叉树== 哈夫曼树越是权值越大的,离根节点越近路径: 一个节点往下子节点,孙子节点的通路路径长度: 当前节点的层数 - 1结点的权值: 赋予节点中某种意义的数值带权路径长度: 节点的权 * 路径长度public class HuffmanTree { public static void main(String[] args) { int [] arr = {13,7,8,3,29,6,.原创 2020-07-29 18:04:37 · 1046 阅读 · 0 评论 -
堆排序
堆排序 【重点】 堆排序是一种利用堆这种结构设计的排序算法,是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。大顶堆:每个节点的值都大于其左右子节点的值从小到大排序小顶堆:每个节点的值都小于其左右子节点的值从大到小排序 先将数组序列构造成大小顶堆,然后再通过顶点(根结点) 与 末尾元素进行交换,同时下一次调整堆结构的时候有效长度减一。public class HeapSort { public static void ma.原创 2020-07-28 13:52:21 · 76 阅读 · 0 评论 -
线索化二叉树
线索化二叉树中序线索化遍历只能是中序线索化后的二叉树前序线索化遍历只能是前序线索化后的二叉树后序线索化遍历只能是后序线索化后的二叉树 后序线索化比较复杂。中序线索化前序线索化后序线索化二叉树节点/** * 节点 */class LanNode { public Integer id; public String name; public LanNode left; public LanNode right; publ.原创 2020-07-27 22:50:50 · 136 阅读 · 0 评论 -
顺序存储二叉树
顺序存储二叉树说明: 可以将二叉树中的节点数据转换成数组的形式存储,又可以将数组中的数据转换成二叉树形式存储,可以相互转换特点:顺序二叉树一般只考虑完全二叉树在数组中2.1 第 index 个数据的 左子节点 为 2*index + 12.2 第 index 个数据的 右子节点 为 2*index + 22.3 第 index 个数据的 父节点 为 (index - 1) / 2class ArrBinaryTree { private int[] arr; p.原创 2020-07-26 21:00:51 · 94 阅读 · 0 评论 -
无规则简单二叉树
无规则二叉树封装的挺好的感觉这种写法前序遍历:根左右中序遍历:左根右后序遍历:左右根 前序、中序、后序查找:类似遍历二叉树 class BinaryTree{ private HeroNode root; public BinaryTree(HeroNode root) { this.root = root; } /** * 前序遍历 .原创 2020-07-26 20:08:43 · 159 阅读 · 0 评论 -
查找算法
查找算法思路:二分查找:根据 left 左边界、right 右边界,(left + right) / 2 求出中间下标 mid 以及 中间值 midValue在 left <= right 的条件下,查找值 findValue 与 中间值midValue 比较。2.1 findValue > midValue : 查找值大于中间值,将左边界更新为 mid + 12.2 findValue < midValue :查找值小于中间值,将右边界更新为 mid - 12.原创 2020-07-26 09:22:22 · 186 阅读 · 0 评论 -
排序算法
排序算法;冒泡排序 :每次循环将最大的一个数冒泡到正确的位置选择排序:每次循环将最小的一个找出,替换到对应位置简单插入排序:3.1 从小到大排序: 规定需要插入的数insertValue,遍历将前一个覆盖后一个,直到遇到前一个 < insertValue, 将后一个变为 insertValue 的值希尔排序 :4.0 将数组分组,group = arr.length / 2 分两组,group 为步长,如果前面的大于后面的,则进行交换.4.1 交换式 : 设置中间变量,复制替换.原创 2020-07-24 13:12:16 · 137 阅读 · 0 评论 -
八皇后问题(递归)
八皇后问题-递归思路:解法存储思路: 一维数组,arr[8], 下标表示第 n 个(行)皇后, value 表示第 n 个皇后所在的列判断第 n 个皇后与前面摆放的 n - 1 个皇后是否冲突2.1 因为一维数组,下标++,不会发生行冲突2.2 判断列冲突 arr[n] == arr[i]2.3 判断斜线: 利用斜率 : (y1-y2) / (x1 - x2) = 1摆放棋子:3.1 结束条件:判断是否摆完3.2 循环 i = 0 至 8 , 遍历每一行的列3.3 若不冲突,递归调.原创 2020-07-22 23:19:24 · 279 阅读 · 0 评论 -
迷宫回溯
迷宫回溯:从某一处走向某一处思路:二维数组–地图初始化墙体约定: map[][] = 0 未走过, map[][] = 1 墙, map[][] = 2 可以走通, map[][] = 3 走过,走不通策略: 下 --> 右 --> 上 --> 左 , 该点走不通,回溯public class MiGong { public static void main(String[] args) { int[][] map = new int[8][.原创 2020-07-22 21:14:13 · 82 阅读 · 0 评论 -
中缀表达式转换成后缀表达式
中缀表达式转后缀表达式思路:三个方法: ① 将中缀表达式转换成 中缀表达式对应的 List ② 自定义运算符优先级 ???? 将中缀表达式对应的 list 转换成 后缀表达式.1.1 使用 list 更好的和 stack 配合,list 比 字符串的遍历更加灵活.将中缀表达式对应的 list 转换成 后缀表达式2.1 需要两个栈: 运算符栈 s1、存储临时结果栈(为了方便使用 List<String> 代替 Stack<String> ) s22.2 遍历 中缀Li原创 2020-07-20 21:25:46 · 619 阅读 · 0 评论 -
逆波兰计算器(后缀表达式)
后缀表达式: (3+4)x 5 - 6 -----> 后缀表达式: 3 4 + 5 x 6 -从 左 到 右 扫描: 遇到数字压入栈中,遇到 符号 将数字弹出栈进行运算,运算结果再放入栈中。前缀表达式: (3+4)x 5 - 6 -----> 前缀表达式: + x - 3 4 5 6从 右 到 左 扫描: 遇到数字压入栈中,遇到 符号 将数字弹出栈进行运算,运算结果再放入栈中。 逆波兰计算器:思路:将 String suffixExpression 转为 ArrayL.原创 2020-07-20 18:13:58 · 227 阅读 · 0 评论 -
栈实现综合计算器(中缀表达式)
栈: 计算器–运算 思路:自己定义符号优先级 priority判断是否为符号 isOper进行运算 cal需要两个栈 — 数栈、符号栈定义需要的相关变量 index、num1、num2、res、oper、ch分解表达式判断当前字符 是 数字 还是 符号7.1 如果是数字,直接压入数栈中7.2 如果是符号7.2.1 判断符号栈是否为空7.2.2 为空: 将符号直接压入7.2.3 不为空: 判断当前符号 与 符号栈栈顶符号的优先级谁高7.2.4 当前.原创 2020-07-20 16:30:49 · 255 阅读 · 2 评论 -
单链表模拟栈
小练习 /** * 单链表模拟栈 */ class LinkedListStack { // 头指针 private StackNode head = new StackNode(); /** * 压入栈中. * * @param data */ public void push(int data) { S.原创 2020-07-20 13:38:00 · 153 阅读 · 0 评论 -
数组模拟栈
栈: 先进后出maxSizearrtop /** * 数组模拟栈 */ class ArrayStack<T>{ private int maxSize; // 数组最大容量 private T[] arr; // 数组 private int top = -1; // 栈顶指针 // 构造器-初始化 public ArrayStack(int maxSi.原创 2020-07-20 13:15:38 · 139 阅读 · 0 评论 -
环形链表
环形链表: 不带头的单向环形链表,最后一个节点的 next 指向 first 节点. 构成环形构建: 第一个节点比较特殊, 需要单独创建遍历: curr.next == first 结束Josephu 约瑟夫问题:小孩出圈: 一共有nums个小孩,从 startNo 个孩子开始数(包括他自己), 数到 k 的那个小孩节点出圈。然后下一个继续从1开始,直到剩下最后一个, first == helper思路:参数合法性判断 k startNo nums创建辅助指针helper,同时将 he.原创 2020-07-20 12:07:12 · 132 阅读 · 0 评论 -
双向链表
双向链表: 可以向前遍历,又可以向后遍历(next、pre)删除: 可以直接找到要删除的节点,进行自我删除,而单链表需要临时节点。添加: 连接 next 、pre修改:双向链表节点思路与单向链表的修改类似。 /** * 双向链表 */ class DoubleLinkedList{ private DoubleNode head = new DoubleNode(); /** * 添加节点 .原创 2020-07-20 09:23:25 · 105 阅读 · 0 评论 -
单链表
单链表的节点长度遍历一遍…求单链表中的倒数第k个节点思路: 使用两个指针向后遍历链表,第一个指针先移动 (k-1) 个位置, 然后两个指针一起移动,当第一个到达最后一个节点时, 第二个指针刚好在倒数第k个节点的位置上。 /** * 查找倒数第 k 个节点 * @param k */ public void getBackCount(int k){ HeroNode cnt =.原创 2020-07-19 22:42:34 · 83 阅读 · 0 评论 -
单链表-添加-修改-删除
单链表: 在内存结构的物理地址中,一般是不连续的, 在逻辑结构上,是连续的。在删除单链表时, 实际就是将当前删除的上一个节点next 指向 当前删除的下一个节点,而这个当前删除的节点并不需要我们手动的或是怎样释放它占有的资源, 当内存不足、或者某些条件触发了jvm垃圾回收时,会回收掉没有任何引用指向它的这块资源。 /** * 链表 */ class SingleLinkedList { /** * 初始化头节点, 头节点不要.原创 2020-07-19 16:43:05 · 519 阅读 · 0 评论 -
数组模拟队列
基本变量 : front、rear、maxSize、arr这里预留了一个空间没有被使用, 主要是要搞好让数组模拟队列循环使用,通过 % 运算, 判断为空、判断是否满了、获取队列有效的长度。 /** * 数组模拟队列 */ class ArrayQueue<T>{ private int front; // 指向队列头的第一个位置 private int rear; // 指向队列尾的最后一个数据 p.原创 2020-07-19 14:15:07 · 184 阅读 · 0 评论 -
稀疏数组
稀疏数组: 将数组中过多的表示为无意义的数压缩成一个比较小的记录有意义的数的数组。 /** * 稀疏数组 */ @Test public void SparseArray() { int[][] array = new int[11][11]; array[1][2] = 1; array[2][3] = 2; for (int[] row : array) { for (.原创 2020-07-17 14:33:00 · 78 阅读 · 0 评论