![](https://img-blog.csdnimg.cn/2020062203364240.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
数据结构与算法
文章平均质量分 94
数组链表、栈与堆、队列、哈希表、树与图、算法设计方法...
Java架构何哥
从事政务信息化、大数据治理、智慧党建相关工作
展开
-
数据结构复习大纲
前言:1976年,一个瑞士计算机科学家写一本书《Algorithms + Data Structures = Programs》。即:算法 + 数据结构 = 程序。40多年过去了,这个等式依然成立。数据是程序的核心要素,因此数据结构的价值不言而喻。无论你在写什么程序,你都需要与数据打交道,比如员工工资、股票价格、杂货清单或者电话本。在不同场景下,数据需要以特定的方式存储,我们有不同的数据结构可...原创 2019-01-04 22:18:20 · 2171 阅读 · 1 评论 -
最常用的五种算法设计思想
1、分治法概念:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。思想策略:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。特征: 该问题的规模缩小到一定的程度就可以容易地解决 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。 利用该问题分解出的子问原创 2021-04-07 00:10:10 · 1399 阅读 · 0 评论 -
快速排序算法思想及其优化
前言:快速排序算法是一种排序执行效率很高的排序算法,平均时间复杂度为O (nlogn),明显优于其他排序算法。而且各大互联网公司会高频率问到的快速排序,所以有必要好好学习一下。一、排序算法简介1、排序算法分类十种常见排序算法可以分为两大类:比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。..原创 2020-06-23 18:17:05 · 4984 阅读 · 0 评论 -
算法设计方法4:动态规划经典例题总结
前言:各大公司关于动态规划的笔试题太多了,必须得掌握。上篇文章提过,使用动态规划的五大步骤:1. 判题题意是否为找出一个问题的最优解2. 将原问题分解为子问题3. 从下往上分析问题 ,找出这些问题之间的关联(状态转移方程),如何从一个或多个已知状态求出另一个未知状态的值。(递推型)4. 讨论底层的边界问题,确定一些初始状态(边界状态)的值,并用数组存储初始子问题的解5. 解决问题(通...原创 2019-03-05 03:54:26 · 4453 阅读 · 2 评论 -
算法设计方法3:动态规划
前言:动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。在各大公司的笔试题中,有关动态规划的题目会经常出现。有很多问题,用贪婪法和分治法无法简洁而高效的解决,但是用动态规划就可以。比如0/1背包问题,其中物品不可拆分,使用贪婪法可能不能得到最优解。但是贪心算法适用于可拆分的物品的背包问题,通过性价比排名就可以进......原创 2019-03-04 03:46:33 · 2404 阅读 · 0 评论 -
算法设计方法2:分而治之
前言:分而治之策略不仅被君主和殖民者成功地用来统治殖民地,也可以用来设计有效的计算机算法。分而治之方法把一个问题的实例分解为若干个小型而独立的实例,从而可以在并行计算机的不同处理器上完成。分而治之方法可以解决如下问题:最大最小问题、矩阵乘法、一个娱乐数学—残缺棋盘问题、排序、选择和一个计算几何问题—在二维空间中寻找距离最近的两个点。一、分而治之的概念1、分而治之的定义“分而治之”( ...原创 2019-03-03 03:48:18 · 1801 阅读 · 0 评论 -
算法设计方法1:贪心算法
前言:走出数据结构的世界,进入算法设计的天地 。为了满足人们对大数据量信息处理的渴望,为解决各种实际问题,计算机算法学得到了飞速的发展,线性规划、动态规划、贪心策略等一系列运筹学模型纷纷运用到计算机算法学中,产生了解决各种现实问题的有效算法。虽然设计一个好的求解算法更像是一门艺术而不像是技术,但仍然存在一些行之有效的、能够用于解决许多实际问题的算法设计方法,你可以使用这些方法来设计算法,并观察这些...原创 2019-03-02 23:14:50 · 3619 阅读 · 0 评论 -
数据结构基础27: DFS和BFS算法总结
前言:图的遍历算法DFS和BFS是许多图算法的基础,所以有必要单独拎出来总结一下。DFS和BFS主要是运用于对于图和树的搜索,很多问题模型都是可以建模变成一个图或者树的,所以差不多不少问题都会涉及到这两个。比如求二叉树深度,可以是递归的方法,属于DFS(深度优先搜索);另一种方法是按照层次遍历,属于BFS(广度优先搜索),想看代码的可以看《剑指Offer(三十八):二叉树的深度》。再比如寻找一条路...原创 2019-02-16 05:06:04 · 5415 阅读 · 2 评论 -
数据结构基础26:图
前言:线性表和树两类数据结构,线性表中的元素是“一对一”的关系,树中的元素是“一对多”的关系。而图是一种比线性表和树更复杂的数据结构,在图中,结点之间的关系是任意的,任意两个数据元素之间都可能相关,图是一种“多对多”的数据结构。在计算机科学中,图是最灵活的数据结构之一,很多问题都可以使用图模型进行建模求解。例如:生态环境中不同物种的相互竞争、人与人之间的社交与关系网络、化学上用图区分结构不同但分子...原创 2019-02-15 05:36:23 · 837 阅读 · 0 评论 -
数据结构基础25:B树和B+树的区别
前言:B-树,即为B树。因为B树的原英文名称为B-tree,而国内很多人喜欢把B-tree译作B-树,其实,这是个非常不好的直译,很容易让人产生误解。如人们可能会以为B-树是一种树,而B树又是一种树。而事实上是,B-tree就是指的B树。数据库索引的数据结构基础就是B+树,B+树是平衡n叉排序树,属于B树的变种,通常用于数据库和操作系统的文件系统中,比B树更适合作索引的存储结构。一、出现背景...原创 2019-02-13 05:43:05 · 878 阅读 · 0 评论 -
数据结构基础24:索引查找和二分查找
一、查找技术的分类图片转自网络二、顺序查找(无序表)顺序查找的原理很简单,就是遍历整个列表,逐个进行记录的关键字与给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录。如果直到最后一个记录,其关键字和给定值比较都不等时,则表中没有所查的记录,查找失败。时间复杂度是O(n)三、二分查找(有序表)前提就是有序表,二分查找的基本思想是:在有序表中,取中间记录作...原创 2019-02-13 05:42:58 · 1816 阅读 · 0 评论 -
数据结构基础23:TopN问题
前言:如果实时展现热门文章,比如近8小时点击量最大的文章前100名。如果是你来开发这个功能,你怎么做?1、TopN排行榜问题描述:在系统中,我们经常会遇到这样的需求:将大量(比如几十万、甚至上百万)的对象进行排序,然后只需要取出最Top的前N名作为排行榜的数据,这即是一个TopN算法。常见的解决方案有三种:(1)直接使用List的Sort方法进行处理。(2)使用排序二叉树进行排序,...原创 2019-02-13 05:42:45 · 1352 阅读 · 0 评论 -
数据结构基础22:堆应用之堆排序
前言:堆可以用来实现n个元素的排序,所需时间为O(nlogn)。先用n个待排序的元素来初始化一个大根堆,然后从堆中逐个提取(即删除)最大元素。结果,这些元素按照非递增的顺序排列。初始化的时间为O(n),每次删除的时间为O(logn),因此总时间为O(nlogn)。这个排序时间比普通排序算法的如冒泡排序、插入排序等的时间O(n^2)要快。一、堆排序的定义堆排序(Heapsort)是指利用堆...原创 2019-02-12 02:38:22 · 698 阅读 · 0 评论 -
数据结构基础21:堆
前言:堆是实现优先级队列效率很高的数据结构,堆其实是一颗特殊的完全二叉树,用下标从1开始的数组表示最有效率。在JVM中,堆是用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配。堆是所有线程共享的,因此在其上进行对象内存的分配均需要进行加锁,这也导致new对象的开销比较大。栈:内存空间小一些,栈的内存要远远小于堆内存,如果你使用递归的话,那么你的栈很快就...原创 2019-02-12 01:53:59 · 1513 阅读 · 0 评论 -
数据结构基础20:字典树的应用场景
(1) 字符串检索事先将已知的一些字符串(字典)的有关信息保存到trie树里,查找另外一些未知字符串是否出现过或者出现频率。举例:1.给出N 个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。2.给出一个词典,其中的单词为不良单词。单词均为小写字母。再给出一段文本,文本的每一行也由小写字母构成。判断文本中是否含有任何不良单词。例如,若ro...转载 2019-02-03 01:25:48 · 2053 阅读 · 0 评论 -
数据结构基础19:字典树
前言:字典树(Trie)可以保存一些字符串->值的对应关系。基本上,它跟 Java 的 HashMap 功能相同,都是 key-value 映射,只不过 Trie 的 key 只能是字符串。Trie 的强大之处就在于它的时间复杂度。它的插入和查询时间复杂度都为 O(k) ,其中 k 为 key 的长度,与 Trie 中保存了多少个元素无关。Hash 表号称是 O(1) 的,但在计算 hash...原创 2019-02-03 01:21:56 · 456 阅读 · 0 评论 -
数据结构基础18:二叉搜索树的搜索、插入、删除和升序输出
前言: HashMap 的底层实现中用到了红黑树,红黑树其实是二叉搜索平衡树,我们先了解一下二叉搜索树。哈希表的字典操作(查找、插入和删除)的平均时间复杂度为Θ(1),而这些操作在坏的情况下能的时间与字典的元素个数呈线性关系。当HashMap的链表长度超过8时,就需要用到平衡二叉搜索树红黑树,红黑树的字典操作时间复杂度为o(logN),能保证哈希冲突过多时的性能;而且二叉搜索树中的节点是有顺序...原创 2019-02-02 23:26:29 · 1563 阅读 · 0 评论 -
数据结构基础17:二叉树应用之算术表达式求值
前言:二叉树的一种应用是无歧义地表示代数、关系或逻辑表达式。在上个世纪20年代初期,波兰的逻辑学家发明了一种命题逻辑的特殊表示方法,允许从公式中删除所有括号,称之为波兰表示法。但是,与原来带括号的公式相比,使用波兰表示法降低了公式的可读性,没有得到广泛的使用。在计算机出现后,这一表示法就很有用了,特别是用于编写编译器和解释器。用户输入的待求表达式,也就是中缀表达式,对于人来说,这个很好理解,但是对...原创 2019-02-01 02:33:28 · 10496 阅读 · 0 评论 -
数据结构基础16:递归
前言:遍历二叉树,是学习树这种数据结构首先要理解的一种基本操作,比较简单地方式就是用递归去遍历。鉴于递归这种调用方法有一定的特殊性,本篇博客就来介绍一下递归的定义以及几个递归的经典算法题。一说起递归,我想每个人都不陌生。举个从小就听过的例子:从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山...这其实是抽象出来的递归现象,但...原创 2019-01-29 00:49:37 · 3314 阅读 · 0 评论 -
数据结构基础15:二叉树的前序、中序和后序遍历
前言:到目前为止,我们已经介绍了线性数据结构和表数据机构(哈希表)。这些数据机构一般都不适合表示具有层级结构的数据。在层次化的元素之间有祖先—后代、上级—下属、整体—部分以及其他类似的关系。一、树的介绍1、树的定义:树状图是一种数据结构,它是由n(n>=0)个结点组成一个具有层次关系的有穷集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。n=0...原创 2019-01-28 19:56:49 · 4337 阅读 · 0 评论 -
数据结构基础14:深入解析HashMap源代码
前言:本文的 HashMap 源码是基于Jdk1.8版本的。 一、HashMap的底层实现原理Java 8.0后,HashMap的底层实现是数组+链表+红黑树。HashMap的底层实现是用哈希表,而Java中实现哈希表的数据结构是数组+链表。其中,当链表长度超过8时,会自动使用红黑树代替,红黑树的查找时间复杂度为O(logn)。1、HashMap的底层主要是基于数组和链表来...原创 2019-01-28 19:26:11 · 354 阅读 · 0 评论 -
数据结构基础13:HashMap使用总结
一、HashMap的定义HashMap是基于哈希表的 Map 接口的实现,它存储的内容是键值对(key-value)映射,其中元素的排列顺序是不固定的。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。另外,HashMap是非线程安全的,也就是说在多线程的环境下,可能会存在问题;而Hashtable是线程安全的,但由于同步需要花时间,所以效率没有HashMap好,...原创 2019-01-28 00:17:26 · 370 阅读 · 0 评论 -
数据结构基础12:HashMap和Hashtable的区别
前言:HashMap是基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。另外,HashMap是非线程安全的,也就是说在多线程的环境下,可能会存在问题,而Hashtable是线程安全的,但由于同步需要花时间,所有效率没有HashMap好。由于历史原因,HashTable基本被弃用了,日常开发中我们习惯使用HashMap。1、产生时间H...原创 2019-01-27 17:15:40 · 741 阅读 · 0 评论 -
数据结构基础11:哈希表应用之LZW压缩
一、LZW的介绍定义:LZW算法又叫“串表压缩算法”就是通过建立一个字符串表,用较短的代码来表示较长的字符串来实现压缩。特点:LZW和哈夫曼编码一样,是无损压缩中的一种。该算法通过建立字典(HashMap),实现字符重用与编码,适用于source中重复率很高的文本压缩。即对于数据流中连续重复出现的字节和字串,LZW压缩技术具有很高的压缩比。1、LZW编码 (Encoding) 的核心思...原创 2019-01-27 01:31:56 · 1677 阅读 · 0 评论 -
数据结构基础10:哈希表常见问题
一、有两个字典,分别存有 100 条数据和 10000 条数据,如果用一个不存在的 key 去查找数据,在哪个字典中速度更快?有些计算机常识的读者都会立刻回答: “一样快,底层都用了哈希表,查找的时间复杂度为 O(1)”。然而实际情况真的是这样么?答案是否定的,存在少部分情况两者速度不一致。答:在 Java 和 Objective-C 中,如果哈希函数不合理,返回值过于集中,会导致大...原创 2019-01-26 20:48:14 · 698 阅读 · 0 评论 -
数据结构基础9:哈希表
前言:哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景极其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表。还有就是适用于Source中文本重复率高的文本压缩LZW。一、字典字典是由一些形如(k,v)的数对所组成的集合,其中k是关键字,v是与关键字k对应的值。任意一个数对,其关键字都不等。确定字典是否为空 确定字典有多少...原创 2019-01-24 16:44:29 · 643 阅读 · 0 评论 -
数据结构基础8:队列
前言:队列(Queue)是一种先进先出(FIFO)的线性表。特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除。要实现队列,需要设置两个指针进行管理:一个是队头指针front,它指向队首元素;另一...原创 2019-01-23 19:33:38 · 263 阅读 · 0 评论 -
数据结构基础7:栈应用之老鼠迷宫
问题描述:迷宫是一个矩形区域,入口在左上角,出口在右下角。迷宫内部包含不能穿越的墙或障碍物,这些障碍物沿着行和列来放置,与迷宫边界平行。我们需要编程帮助杰瑞老鼠寻找一条从入口到出口的路径。一、问题分析1、首先要有一张迷宫地图,地图由两部分组成: (1)一是迷宫中各处的位置坐标(2)二是迷宫各位置处的状态信息,即该处是墙还是路假定用m*n的矩阵来表示迷宫,迷宫的每个位置都可以用其...原创 2019-01-12 00:19:23 · 1512 阅读 · 0 评论 -
数据结构基础6:栈应用之括号匹配
问题描述:对一个字符串的左右括号进行匹配。输入:一个字符串表达式输出:匹配成功true或匹配失败false例如:假设一个算术表达式中可以包含三种括号:圆括号“()”,方括号“[]”和花括号“{}”,且这三种括号可按任意的次序嵌套使用如:(a+b)[c*({d-e)]},返回false。编写判别给定表达式中所含括号是否正确配对出现的算法。匹配思想:通过观察可以发现,如果从左向右扫描一...原创 2019-01-09 00:50:03 · 742 阅读 · 0 评论 -
数据结构基础5:栈应用之十进制转N进制
一、进制转换基础二进制转为十进制:把二进制数的各个位拆开,分别乘以2的次幂再累加。末尾位乘2的0次幂,依次类推。 比如:1011十进制=1*2^3+1*2^2+1*2^1+1*2^0 =11. 十进制转为二进制除k取余法:主要用于把十进制的数化为k进制的数。例如:把89化为二进制的数89÷2=44 余144÷2=22 余022÷2=11 余011÷...原创 2019-01-08 02:58:33 · 2683 阅读 · 0 评论 -
数据结构基础4:栈
前言:栈(Stack)是一种特殊的线性表,只允许在线性表的一端操作,栈顶允许操作,栈底不允许操作。生活中的栈比如书店的一摞教科书、自助餐厅的一摞餐盘,其工作方式就是后进先出,只要规定取得时候只能从最上面取,然后新的书/盘子放在这摞东西的顶部。栈的特性:后进先出(LIFO)。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶(压栈push),需要读数据的时候从栈顶开始弹出数据(...原创 2019-01-08 01:49:38 · 385 阅读 · 0 评论 -
数据结构基础3:链表常见面试题
前言:单链表的反转、合并两个有序链表和倒序打印链表等算法,是各大公司Java面试开发中常考的题目。一、单链表反转算法思想:所谓的单链表反转,就是把每个节点的指针域由原来的指向下一个节点变为指向其前一个节点。由于单链表没有指向前一个节点的指针域,因此我们需要增加一个指向前一个节点的指针pre,用于存储每一个节点的前一个节点。此外,还需要定义一个保存当前节点的指针cur,以及下一个节点的t...原创 2019-01-06 04:37:28 · 691 阅读 · 0 评论 -
数据结构基础2:链表
前言:线性表的链式描述,是最基本的数据结构,在物理空间上不必连续存储。使用链表结构可以克服数组需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是同时链表由于增加了结点的指针域,空间开销比较大。因为链表失去了数组随机读取的优点,故查询速度要慢点。因为数组的插入删除需要移动大量的元素,而链表只需要改变“链”的关系即可而查询比数组慢,所以其插入、删除操作...原创 2019-01-06 03:14:06 · 533 阅读 · 2 评论 -
数据结构基础1:数组
前言:线性表的数组描述,在物理空间上连续存储,利用索引随机读取元素。线性表:也称为有序表,形如(e0,e1,e2...en-1),n为有穷自然数,可以认为e0先于e1,e1先于e2,除了这种先后关系,线性表不再有其他关系。一、合并两个有序数组题目:给定两个有序整数数组nums1和nums2,将它们合并成新的有序数组nums3算法思路:从两数组的最左边开始,按位循环比较两个数组的...原创 2019-01-05 01:13:08 · 297 阅读 · 0 评论