![](https://img-blog.csdnimg.cn/20200727195534886.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
数据结构和算法
数据结构和算法相当于程序员的内功,越在早期掌握越好
叫我序员就好了
你除了修不完的 bug还有什么?
展开
-
学习笔记-排序算法(基数排序)
介绍基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法基数排序(Radix Sort)是桶排序的扩展基数排序是1887年赫尔曼·何乐礼发明的.它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较.基本思想将所有待比较数值统一为同样的原创 2020-08-24 08:49:24 · 144 阅读 · 0 评论 -
学习笔记-排序算法(归并排序)
介绍归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之).基本思想再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤原创 2020-08-23 14:39:39 · 143 阅读 · 0 评论 -
学习笔记-排序算法(快速排序)
介绍快速排序(Quicksort)是对冒泡排序的一种改进.基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列示意图代码实现public class QuickSort { public static void main(String[] args) { int[] arr = {8,9,7,1,2,3,5,4,6,原创 2020-08-23 09:05:19 · 80 阅读 · 0 评论 -
学习笔记-排序算法(希尔排序)
介绍希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序.基本思想希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止示意图实现逻辑希尔排序第一轮排序 int temp = 0; //将十个数据分成了5组,循环5次(次数) for (in原创 2020-08-19 18:52:18 · 181 阅读 · 0 评论 -
学习笔记-排序算法(插入排序)
介绍插入式排序属于内部排序法,是对于欲排序的元素以插入的方式找寻该元素的适当位置,以达到排序的目的.插入排序法思想插入排序(Insertion Sorting)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表.插入排序思路图实现逻辑以数组int[] arr = {101,34,119,1}为原创 2020-08-18 19:40:11 · 164 阅读 · 0 评论 -
学习笔记-排序算法(选择排序)
基本介绍选择式排序也属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,再依规定交换位置后达到排序的目的.选择排序思想选择排序(select sorting)也是一种简单的排序方法.它的基本思想是:第一次从arr[0] ~ arr[n-1]中选取最小值,与arr[0]交换,第二次从arr[1] ~ arr[n-1]中选取最小值,与arr[1]交换,第三次从arr[2] ~ arr[n-1]中选取最小值,与arr[2]交换,…,第i次从arr[i-1] ~ arr[n-1]中选取最小值,与ar原创 2020-08-17 18:50:09 · 120 阅读 · 0 评论 -
学习笔记-排序算法(冒泡排序)
基本介绍冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒.因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换.从而减少不必要的比较.(这里说的优化,可以在冒泡排序写好后,在进行)图解我们将五个无序的数:3, 9, -1, 10, 20 使用冒泡原创 2020-08-13 19:43:15 · 132 阅读 · 0 评论 -
学习笔记-排序算法(简单介绍)
介绍排序也称排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排列过程分类内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序。外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储行序。常见的排序算法分类算法的时间复杂度1)事后统计的方法:这种方法可行,但是有两个问题:一是要想对设计的算法的运行性能进行评测,需要实际运行该程序;二是所得时间的统计量依赖于计算机的硬件.软件等环境因素,这种方式,要在同一台计算机的相同状态下运行,才能比较那个算法速度更快原创 2020-08-13 16:28:45 · 137 阅读 · 0 评论 -
学习笔记-递归(八皇后)
八皇后问题介绍八皇后问题:是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法。思路分析1)第一个皇后先放第一行第一列2)第二个皇后放在第二行第一列,然后判断是否OK,如果不OK,继续放在第二列.第三列,依次把所有列都放完,找到一个合适3)继续第三个皇后,还是第一列.第二列……直到第8个皇后也能放在一个不冲突的位置,算是找到了一原创 2020-08-07 16:29:22 · 136 阅读 · 0 评论 -
学习笔记-递归(迷宫回溯)
求迷宫的最短路径创建二维数组public static void main(String[] args) { //先创建一个二维数组,模拟迷宫 int[][] map = new int[8][7]; //使用1标识墙 //上下左右置为1 for (int i = 0; i < 7; i++) { map[0][i] = 1; map[7][i] = 1;原创 2020-08-03 19:26:48 · 106 阅读 · 0 评论 -
学习笔记-递归(简单介绍)
概念简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。案例public class digui { public static void main(String[] args) { test(4); } public static void test(int n) { if (n > 2) { test(n-1); }原创 2020-07-30 19:55:40 · 108 阅读 · 0 评论 -
学习笔记-中缀表达式转后缀表达式
思路分析1)初始化两个栈:运算符栈s1和储存中间结果的栈s2;2)从左至右扫描中缀表达式;3)遇到操作数时,将其压s2;4)遇到运算符时,比较其与s1栈顶运算符的优先级: a.如果s1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈; b.否则,若优先级比栈顶运算符的高,也将运算符压入s1; c.否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4-1)与s1中新的栈顶运算符相比较;5)遇到括号时: a.如果是左括号“(”,则直接压入s1 b.如果是右括号“)”,则依次弹出s1原创 2020-07-29 20:59:04 · 136 阅读 · 0 评论 -
学习笔记-前缀,中缀,后缀(后缀实现综合计算器)
①前缀表达式1)前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前 (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 62)前缀表达式的计算机求值:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素和次顶元素),并将结果入栈.重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果 减法是栈顶减次顶3)例如: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6,针对前缀表达式求值步骤如原创 2020-07-27 19:49:45 · 376 阅读 · 0 评论 -
学习笔记-栈(实现综合计算器)
①思路分析1)通过一个index值(索引),来遍历我们的表达式2)如果我们发现是一个数字,,就直接入数栈3)如果发现扫描到是一个符号, 就分如下情况 a.如果发现当前的符号栈为空,就直接入栈 b.如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,就需要从数栈中pop出两个数,在从符号栈中pop出一个符号,进行运算,将得到结果入数栈,然后将当前的操作符入符号栈,如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈.4)当表达式扫描完毕,就顺序的从数栈和符号栈中原创 2020-07-23 19:40:23 · 98 阅读 · 0 评论 -
学习笔记-栈(使用数组实现)
(1)引入计算机底层是如何运算的得到结果,注意不是简单的把算式列出运算,计算机怎么理解这个算式的(对计算机而言,它接受到的就是一个字符串) ->栈(2)介绍①栈的英文为(stack)②栈是一个先入后出的有序列表③栈(stack)是限制线性表中元素的插入删除只能在线性表的同一端进行的一种特殊线性表,允许插入和删除的一端,为变化的一端,成为栈顶(Top),另一端为固定的一端,成为栈底(Bottom)④根据栈的定义可知,最先放入栈中元素再栈底,最后放入的元素再栈顶,而删除元素刚好相反,最后放入原创 2020-07-13 20:17:33 · 277 阅读 · 0 评论 -
学习笔记-约瑟夫问题Josephu(单向循环链表解决)
①应用场景(约瑟夫问题Josephu)②思路分析③构建单向的环形链表思路1)先创建第一个节点,让frist指向该节点,并形成环形2)后面当我们每创建一个新的节点,就把该节点加入到已有的环形链表中④遍历环形链表1)先让一个辅助指针(变量)curBoy,指向frist节点2)然后通过一个while循环遍历该环形链表即可,curBoy.next == frist退出⑤根据用户输入,生成一个小孩出圈的顺序n = 5 ,即有5个人.k = 1,从第一个人开始报数.m = 2,数2下1)需原创 2020-07-12 23:03:51 · 282 阅读 · 0 评论 -
学习笔记-双向链表(遍历,新增,修改,删除,有序插入)
思路分析双向链表的遍历,添加,修改,删除的操作思路1) 遍历方法和单链表一样,只是可以向前,也可以向后查找2) 添加 (默认添加到双向链表的最后)(1)先找到双向链表的最后这个节点(2) temp.next = newHeroNode;(3) newHeroNode.pre = temp;3) 修改思路和原来的单向链表一样.4) 删除(1)因为是双向链表,因此,我们可以实现自我删除某个节点(2)直接找到要删除的这个节点,比如temp(3) temp.pre.next = temp.n原创 2020-07-09 20:10:06 · 285 阅读 · 1 评论 -
学习笔记-单链表面试题(有效节点个数,倒数第k个节点,反转,从尾打印,合并)
①求单链表中有效节点的个数(如果带头节点的链表,不统计头节点) //获取单链表的节点的个数(不带头节点) public static int getLength(HeroNode head) { if (head.next == null) {//判断是否为空 return 0; } int length = 0; HeroNode cur = head.next;//临时变量 while原创 2020-07-08 10:45:15 · 121 阅读 · 0 评论 -
学习笔记-单链表(按顺序插入,修改,删除)
按顺序插入节点(分析)代码实现/** * 根据英雄的排名插入到指定的位置 * (如果有这个排名,则添加失败,并给出提示) */ public void addByOrder(HeroNode node) { //因为头节点不能动,我们仍然需要通过一个辅助变量来帮助我们找到指定的位置 //因为单链表,因为我们找的temp是位于添加位置的前一个节点,否则插入不了 HeroNode temp = head;原创 2020-07-02 09:25:53 · 405 阅读 · 0 评论 -
学习笔记-单链表(插入不考虑编号顺序)
介绍链表是有序的列表,但是它在内存中的存储如下(实际的内存图)链表是以节点的方式来存储,是链式存储每个节点都包含data域:存放数据,next域:指向下一个节点如图发现各个节点不一定是相连的链表分为带头节点和没有头节点的链表,根据实际需求来确定逻辑结构示意图需求使用带head头的单向链表实现-水浒英雄排行榜管理分析代码实现定义HeroNode类//定义HeroNode,每个HeroNode对象就是一个节点class HeroNode { public int no原创 2020-06-30 14:50:27 · 95 阅读 · 0 评论 -
学习笔记-循环队列(解决队列无法复用)
分析说明 1. 尾索引的下一个为头索引时表示队列满,即将队列容量空出一个作为约定,这个在做判断队列满的时候需要注意(rear+1)%maxSize == front (满) 2. Rear == front (空) 3. 分析思路 1)front就指向队列的第一个元素,也就是说arr[front]就是队列的第一个元素,front的初始值 = 0 2)rear指向队列的最后一个元素的后一个位置,希望空出一个空间作为约定,rear的初始值 = 0 3)当队列满时,条件是(rear+1)%maxSi原创 2020-06-29 10:00:36 · 214 阅读 · 0 评论 -
学习笔记-稀疏数组(含写入本地和读取)
需求稀疏数组当一个数组的元素包含大量的0时,或者为同一个值的数组时,可以使用稀疏数组来保存该数组处理方式记录数组一共有几行几列,有多少不同的值把具有不同的值的元素的行列及值记录在一个小规模(稀疏数组)的数组中,从而缩小程序的规模效果图相互转换的思路二维数组转稀疏数组的思路1.遍历原始的二位数组,得到有效数据的个数sum2.根据sum就可以创建稀疏数组sparseArr int[sun+1][3]3.将二维数组的有效数据存入到稀疏数组中稀疏数组转原始的二维数组的思路1.先读取稀原创 2020-06-28 14:30:19 · 209 阅读 · 0 评论 -
学习笔记-队列(数组实现)
使用场景模拟银行叫号系统队列介绍队列是一个有序列表,可以用数组或是链表来实现遵循先入先出的原则,即:先存入队列的数据,要先取出,后存入的要后取出队列本身是有序列表,使用数组的结构来存储队列的数据因为队列的输入,输出是分别从前后端来处理,因此需要两个变量front及rear分别记录队列签后端的下标,front会随着数据输出而改变,而rear则是随着数据输入而改变,(入队列rear增加,出队列front增加)示意图数组模拟队列思路分析将尾指针后移.rear+1, front == r原创 2020-06-28 12:15:53 · 116 阅读 · 0 评论