
数据结构和算法
数据结构与算法相关
有机后浪
正在慢慢深入中。。。
展开
-
经典算法 - 回溯法解决骑士周游问题及贪心算法优化
骑士周游问题(马踏棋盘)这是一个很经典的游戏,4399小游戏:马踏棋盘马只能走日字,棋盘每个格子只能走一次,现在要求马跳遍整个棋盘,最终回到最初的位置如果靠人来想挺难的,但是我们有计算机通常采用回溯法或启发式搜索类算法求解回溯法分析:棋盘可以看做一个二维数组chessboard,可以用Point对象代表一个位置一个马最多可以走8个方向,分别标号(这里标号的顺序不同会造成结果不同,都是问题的解)即可以写一个方法判断当前位置curPoint的下一步哪些位置可走(8个for循环)创原创 2020-09-02 11:55:17 · 2621 阅读 · 0 评论 -
经典算法 - 最短路径问题与Dijkstra、Floyd算法
图的最短路径问题前面介绍了图的基本知识:数据结构 - 图与深度优先、广度优先遍历现有一个图:有7个顶点{'A','B','C','D','E','F','G'},顶点间长度为权值假设起点为G,现要求G点到各顶点的最短路径迪杰斯特拉算法(Dijkstra)Dijkstra算法以起始点为中心向外层层扩展(广度优先遍历),采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止百度百科:核心思路:设置3个数组:alreadyArr记录以访问的顶点;preVi原创 2020-09-01 19:00:41 · 434 阅读 · 0 评论 -
经典算法 - 图解图的最小生成树问题与prim、kruskal算法
图的最小生成树前面介绍了图:数据结构 - 图与深度优先、广度优先遍历生成树:无向图G的生成子图是连通且不含回路的无向图,称为G的生成树现有一个图:有7个顶点{'A','B','C','D','E','F','G'},顶点间长度为权值现要保证所有顶点连通且长度最短这个问题就是求最小生成树,有两种经典的算法:prim、kruskal算法普利姆算法(prim)prim算法的核心思想:从起点开始,每次都找到该起点的权值最小的边将该边的另一个顶点加入集合visited,然后找visited集原创 2020-08-31 18:19:59 · 1280 阅读 · 0 评论 -
经典算法 - 贪心算法及集合覆盖问题
贪心算法贪心算法:在对问题求解时,总是做出在当前看来是最好的选择是由局部到整体,算法得到的是在某种意义上的局部最优解,对整体是近似最优解贪心算法一般按如下步骤进行:建立数学模型来描述问题把求解的问题分成若干个子问题对每个子问题求解,得到子问题的局部最优解把子问题的解局部最优解合成原来解问题的一个解(近似于最优解,也可能是最优解)贪心算法特点是一步一步地进行,以当前情况为基础根据作当前的最优选择,通过每一步贪心选择,可得到问题的一个最优解集合覆盖问题一个广播覆盖问题:存在以下广播,原创 2020-08-29 11:52:41 · 3380 阅读 · 4 评论 -
经典算法 - 图解KMP算法与字符串匹配问题
字符串匹配问题字符串匹配问题:有一个字符串str1 = "BBC ABCDAB ABCDABCDABDE";和一个子串str2 = "ABCDABD";现在判断str1是否含有str2,存在返回匹配的第一次位置,不存在返回-1暴力匹配法思路首先想到的就是暴力匹配法:设计两个指针i,j,分别指向两个字符串,i向右移与str2[j]比较一直比较到值相同的位置,i、j后移比较str1[i]与str2[j]的值最终比较str1[10]与str2[6]不同,不匹配再重新原创 2020-08-28 18:47:24 · 303 阅读 · 0 评论 -
经典算法 - 动态规划算法及背包问题(01背包与完全背包)
动态规划动态规划算法通常用于求解具有某种最优解的问题基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,动态规划分解得到的子问题往往不是互相独立的,即上一个子问题解可能为下一个子问题的条件(通常可以将结果填入表格)背包问题有一个背包容量为4kg,现在有以下物品物体重量价格吉他11500音响43000电脑32000现要求装入背包的物体价值最大,且不能超重其中:01背包问题:物品有原创 2020-08-27 16:55:39 · 3346 阅读 · 0 评论 -
经典算法 - 图解分治算法及汉诺塔问题
分治算法分治算法的思想在于“分”和“治” - 分而治之“分”是将大问题分成独立的子问题,最后子问题可以简单的直接求解“治”是将子问题解决,然后合成大问题,大问题的解是子问题解的合并分治算法是很多问题的基本思想:如归并排序、快速排序、二分查找等归并排序:汉诺塔游戏汉诺塔游戏有3个塔,要求将塔1的圆盘放到塔3,条件:一次只能移动一个盘且大盘不能在小盘上,求移动的步骤及次数当1个盘:第一次:...原创 2020-08-24 18:00:44 · 813 阅读 · 0 评论 -
数据结构 - 图与深度优先、广度优先遍历
为了解决问题,从线性结构 -> 树形结构 -> 图形结构1. 线性结构:只有前驱、后继结点,元素是线性关系2. 树形结构:元素有层次关系,每一层上的结点只能和上一层中的至多一个结点相关,但可能和下一层的多个结点相关3. 图形结构:元素之间具有任意关系,任意两个元素都可能相关原创 2020-08-23 16:27:23 · 470 阅读 · 0 评论 -
数据结构 - 图文解析AVL树
什么是平衡二叉树平衡树(Balance Tree,BT) 指的是,任意节点的子树的高度差都小于等于1第二个树根节点左子树高度为3,右子树高度1,高度差为2,不平衡二叉平衡搜索树(AVL树):自平衡的二叉排序树...原创 2020-08-19 17:04:49 · 375 阅读 · 0 评论 -
数据结构 - 图文解析二叉查找树
二叉查找树二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树二叉树查找树是一棵空树,或者是具有下列性质的二叉树:若左子树不空,则左子树上所有结点的值均小于它的根结点的值;若右子树不空,则右子树上所有结点的值均大于它的根结点的值;左、右子树也分别为二叉排序树;没有键值相等的结点现实中可以有键值相等的结点,需要自定义规则相等的结点应该放左子树还是右子树,尽量避免键值相等一棵二叉查找树:二叉查找树的创建遍历如何创建原创 2020-07-04 16:38:22 · 283 阅读 · 0 评论 -
数据结构 - 哈夫曼树及哈夫曼编码:压缩、解压
什么是哈夫曼树?哈夫曼树(Huffman Tree):给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度(WPL)达到最小,这样的二叉树也称为最优二叉树一棵带权二叉树:这里有几个概念:路径:从一个结点到另一个结点经过的所有结点为两结点间的路径,如上图结点A到结点8的路径为:A-B-C-D-8路径长度:树中一个结点到另一个结点的经过的边数,A到结点8的路径长度为4权值:对于树的结点,可以定义一个有某种意义的数值为权重值如结点为商品,我们就可以设置权值为商品价格,权值原创 2020-07-03 15:56:03 · 1955 阅读 · 1 评论 -
排序算法 - 图文解析堆排序
堆(heap)是一类特殊的数据结构,通常可以被看做一棵树的数组对象,也就是顺序存储的树具体的排序思路: 对于已经调整好的大顶堆、小顶堆,我们可以知道根结点是最大值(最小值),且在数组的首位,将堆顶元素与末尾元素交换,使末尾元素最大,然后重新调整堆,再将堆顶元素与末尾元素交换,得到第二大的数据,循环直到数组完成原创 2020-06-30 16:06:27 · 286 阅读 · 0 评论 -
数据结构 - 图文解析线索二叉树及遍历
什么是线索二叉树一个普通的二叉树,使用链式存储:对于n个结点的二叉树,在二叉链存储结构中有n+1个空链域,利用这些空链域存放在某种遍历次序下该结点的前驱结点和后继结点的指针,这些指针称为线索,加上线索的二叉树称为线索二叉树对于上面的二叉树,结点:8,10,14,6存在空指针,8,10,14左右结点指针都为null,6的右指针为null,如果把左指针连接上前驱结点,右指针连接上后继结点,这就是线索化如果该二叉树结点都线索化,就是线索二叉树前驱结点、后继结点在不同的遍历方式下会不同,所以线索二叉原创 2020-06-21 19:15:41 · 1510 阅读 · 0 评论 -
数据结构 - 解析二叉树的顺序存储
顺序存储结构二叉树的存储结构可以分为两种:顺序存储:使用线性表(数组)存储二叉树链式存储:使用链表存储二叉树在上篇文章:数据结构 - 树、二叉树及四种遍历解析实现使用链式存储二叉树,这篇完成顺序存储顺序存储的特点以数组的方式存放二叉树,要完成4种遍历方式,需要数组与树结点存在对应关系顺序存储二叉树的特点顺序二叉树通常只考虑完全二叉树第n个元素的左子结点为 2 * n + 1第n个元素的右子结点为 2 * n + 2第n个元素的父结点为 (n - 1) / 2n表示数原创 2020-06-21 15:08:17 · 1794 阅读 · 0 评论 -
数据结构 - 树、二叉树及四种遍历解析实现
树我们常用数组、链表存储数据,但这两者都各有优缺点:数组:访问速度快,增加、删除速度慢,需要创建新数组链表:增加、删除快,访问慢,访问时需要从头开始遍历有什么能综合两个优点,提高存取、访问效率的数据结构?提出了树的数据结构:树是一种数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父原创 2020-06-20 17:02:13 · 612 阅读 · 0 评论 -
数据结构 - 哈希表解析实现
哈希表Hash表也称散列表,也可以直接译作哈希表,Hash表是一种根据关键字值(key - value)映射到表中的一个位置而直接进行访问的数据结构,这个映射函数叫散列函数(哈希函数)(链地址法哈希表)哈希表基于数组实现,通过把关键字映射到数组的某个下标(哈希函数)来加快查找速度,查找某个关键字对于哈希表来说,只是O(1)的时间级什么是散列函数散列函数:将关键字装换为数组的特定下标,这种转换的函数就是哈希函数若对于关键字集合中的任一个关键字,经散列函数映象到地址集合中任何一个地址的概率是相等原创 2020-06-16 21:36:24 · 453 阅读 · 0 评论 -
查找算法 - 图文解析二分查找、插值查找、斐波拉契查找算法
查找算法经典的查找算法有7种:顺序查找,二分查找,插值查找,斐波那契查找,树表查找,分块查找,哈希查找其中顺序查找没得说,就是简单的按照顺序从前往后查,一个for循环就解决了这篇文章将解析二分查找、插值查找、斐波拉契查找,这三种查找算法其实都类似,只是优化了分段的方式插值查找、斐波拉契查找是二分查找的优化二分查找二分查找:顾名思义,要将查找的线性表分成两段用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定原创 2020-06-14 16:14:18 · 571 阅读 · 0 评论 -
排序算法 - 计数排序与桶排序
前言比较类排序就是需要通过比较数组中的数据来交换位置,实现有序而非比较类,例如基数排序,就不需要比较,只用不断的分发到不同的桶,然后重新赋值给原数组,最终就可以达成有序前面比较类排序除了堆排序都完成了,非比较类完成了基数排序这篇将讲述计数排序、桶排序,与基数排序类似实际上计数排序、基数排序就是特殊的桶排序,桶排序是一种排序的思想,其实现包括计数排序和基数排序两种原创 2020-05-31 23:01:57 · 800 阅读 · 0 评论 -
排序算法 - 基数排序图文解析实现
基数排序基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O(nlog®m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法简单来说,基数排序就是设置10个桶表示0~9,将要排序的元素先根据所有数的个位数分发到10个桶,然后按顺序重原创 2020-05-30 21:02:12 · 749 阅读 · 0 评论 -
排序算法 - 归并排序图文解析
归并排序归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并归并排序(分治法):分:将元素序列不断细分,分到最小子序列段(递归处理)治:合并、排序,递归分子序列段,回溯返回时合并排序递归的思想解决:分方法一共执行了7次归并排序具体步骤排序[8, 4, 5,原创 2020-05-30 15:43:52 · 425 阅读 · 0 评论 -
排序算法 - 快速排序图文解析
快速排序快速排序(Quicksort)是对冒泡排序的一种改进它的基本思想是:设置一个中间数,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据比中间数小,另外一部分比中间数大然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列简单总结一下实现步骤:设置中间数、左指针、右指针,中间数可以随便设置(有的设置为最左边、最右边的数,我设置为中间的数arr[ (left+right)/2 ])设置辅助变量l = left;r原创 2020-05-28 20:25:47 · 662 阅读 · 0 评论 -
排序算法 - 希尔排序过程【移位】【交换】与速度测试
插入排序的缺陷插入排序是定义有序表、无序表,将无序表元素一个个插入有序表但当存在小数据位于无序表末尾1,2,3,4,5,6,7,0,插入排序时,最后一轮需要赋值8次,十分影响效率有没有办法解决呢?对于插入排序的优化,提出了希尔排序希尔排序希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因D.L.Shell于1959年提出而得名。希尔排序是把原创 2020-05-28 16:07:31 · 586 阅读 · 1 评论 -
排序算法 - 插入排序算法及速度测试
插入排序算法插入排序,一般也被称为直接插入排序。它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动插入排序的精髓在与将元素序列分成有序表和无序表,有序表初始为第一个元素(只有一个元素当然有序),然后一个个判断无序表的第一个元素,将其插入有序表中,保证有序表一直有序,直到无序表为空结束Java实现插入排序算法的过程先一步步实现插入排序的过程原创 2020-05-27 21:23:11 · 655 阅读 · 0 评论 -
排序算法 - 选择排序算法过程及耗时比较
选择排序算法选择排序算法是一种不稳定的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完Java实现选择排序过程先一步一步的实现:设置一个minIndex表示最小数的索引min表示最小的数每一趟遍历都重新假设最开始的数为最小数package com.company.sort;import java.util.Arrays;原创 2020-05-27 19:38:11 · 681 阅读 · 0 评论 -
排序算法 - 冒泡排序过程及优化
冒泡排序冒泡排序:重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。类似与有两个指针指向想邻的两个元素,比较这两个元素(上面的是比较大小,大的元素移动到右边)第一趟排序:2与-1比较,2比-1大,2移动到右边 [-1, 2, 8, -5, 10],指针后移,指向第二、第三位置2与8比较,8比2大,不移动 [-1, 2, 8, -5, 10],指针后移,指原创 2020-05-27 16:57:37 · 494 阅读 · 0 评论 -
需要了解的时间复杂度、空间复杂度
前言运用不同算法涉及效率都是用算法复杂度:(时间复杂度、空间复杂度)来表示,具体是什么?时间复杂度算法的时间复杂度是一个函数,它定性描述该算法的运行时间感觉时间复杂度就是执行算法所需的计算工作量,通常用O(f(n))表示算法运行时间在不同的机器上会不同,所以时间复杂度只是简化的比较常见的时间复杂度量级有:常数阶O(1)对数阶O(logn)线性阶O(n)线性对数阶O(nlo...原创 2020-02-07 16:07:19 · 1051 阅读 · 0 评论 -
数据结构 - 递归实现八皇后问题(回溯算法)
八皇后问题八皇后问题,一个古老而著名的问题,是回溯算法的典型案例。该问题由国际西洋棋棋手马克斯·贝瑟尔于 1848 年提出:在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有 76 种方案。1854 年在柏林的象棋杂志上不同的作者发表了 40 种不同的解,后来有人用图论的方法解出 92 种结果在这个8 * 8的棋盘放置8个皇后,不能同行、同列、同一斜线,计算有多少种可能实现思路穷举法:有 8^8 =167原创 2020-05-26 14:51:23 · 629 阅读 · 0 评论 -
数据结构 - 递归思想及递归实现迷宫问题
递归递归:就是自己调用自己,然后一层层返回一个简单的例子:打印问题: public static void main(String[] args) { test(4); } //打印问题 public static void test(int n){ if (n > 2){ test(n-1); } System.out.println("n = "+ n); }我们可原创 2020-05-26 11:41:19 · 803 阅读 · 0 评论 -
数据结构 - 中缀表达式转后缀表达式及逆波兰计算器实现
前言前面实现了一个中缀表达式计算器:数据结构 - 栈、栈实现计算器中缀表达式是我们平常书写的表达式1+((2+3)*4)-5,但不符合计算机的运算,所以我们设计计算器的时候异常的复杂,设计了数栈、符号栈以及多种规则才实现了简单的表达式计算后缀表达式1 2 3 + 4 * + 5 -更符合计算机的运算,设计一个后缀表达式计算器Java实现后缀表达式计算器对于提供的一个后缀表达式3 4 + 5 * 6 -(默认空格分开),我们如何计算?先把表达式分割成一个list[3, 4, +, 5, *,原创 2020-05-26 09:10:35 · 762 阅读 · 0 评论 -
数据结构 - 栈、栈实现计算器
栈的概念栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素一种受限的线性表:仅能在表尾插入(入栈)、删除(出栈)表尾称为栈顶;另一端称为栈底栈:先进后出Java基于数组实现栈基于数组的栈有三个成员变量:maxSize原创 2020-05-24 18:00:22 · 1623 阅读 · 0 评论 -
数据结构 - 双向链表、单向环形链表、约瑟夫问题实现
双向链表单向链表:单链表是一种链式存取的数据结构,用一组地址任意(不需要地址连续)的存储单元存放线性表中的数据元素,可以使用零碎的空间链表中的数据是以节点来表示的,每个节点的构成:元素(数据元素的映象)+ 指针(指示后继元素存储位置),元素就是存储数据的存储单元value,指针就是连接每个节点的地址数据next单链表是单向的,当访问一个节点后,只能接着访问后继节点单链表可以设置头节点,头节点为空单向链表的特点是只能遵循链式的顺序从链表头节点到尾节点而双向链表是在单向链表的基础上,新增一个前原创 2020-05-24 14:04:23 · 425 阅读 · 0 评论 -
数据结构 - 单链表及相关问题实现
单链表单链表是一种链式存取的数据结构,用一组地址任意(不需要地址连续)的存储单元存放线性表中的数据元素,可以使用零碎的空间链表中的数据是以节点来表示的,每个节点的构成:元素(数据元素的映象)+ 指针(指示后继元素存储位置),元素就是存储数据的存储单元value,指针就是连接每个节点的地址数据next单链表是单向的,当访问一个节点后,只能接着访问后继节点单链表可以设置头节点,头节点为空Java实现单链表通过Java实现单链表,用于表示水浒传好汉:设置对象HeroNode表示节点设置链原创 2020-05-23 20:56:32 · 423 阅读 · 0 评论 -
数据结构 - 队列、环形队列
队列队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,队列是一种操作受限制的线性表,队列又称为先进先出(FIFO—first in first out)线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头常说的队列是指单向队列:Java实现单向队列通过操作尾指针rear、头指针front、数组可以模拟单向队列ArrayQueue构造器:初始化数组,头、尾指针都为0头指针指向队列第一个元素尾指针指向队列最后一个元原创 2020-05-20 17:24:57 · 262 阅读 · 0 评论 -
数据结构 - 稀疏数组转换
稀疏数组概念当一个数组仅包含一定的数据,其他的都是初始化数据0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0原创 2020-05-19 17:09:17 · 214 阅读 · 0 评论