算法
文章平均质量分 79
sb___itfk
这个作者很懒,什么都没留下…
展开
-
并查集
并查集是什么并查集是一种用来管理元素分组情况的数据结构。并查集可以高效地进行如下操作。不过需要注意并查集虽然可以进行合并操作,但是却无法进行分割操作查询元素a和元素b是否属于同一组合并元素a和元素b所在的组并查集的结构并查集也是使用树形结构实现的,不过不是二叉树。每个元素对应一个节点,每个组对应一棵树。在并查集中,哪个节点是哪个节点的父亲以及树的形状等信息无需多家关注,整体组成一个树形结构才是重要的。(1)初始化我们准备n个节点来表示n个元素。最开始时没有边。(2)合并像下图一转载 2020-06-18 18:48:04 · 704 阅读 · 0 评论 -
KMP算法
KMP 算法的核心思想,跟 BM 算法非常相近。在模式串和主串匹配的过程中,把不能匹配的那个字符仍然叫作坏字符,把已经匹配的那段字符串叫作好前缀。从模式串和主串头部开始匹配,遇到坏字符时模式串向后滑动,可滑动多少呢,这就是KMP算法的关键。好前缀的后缀子串 与 主串的前缀子串 匹配存在时,模式串就不能向后滑动模式串长度个位置了。为了能够快速得到不匹配是向后滑动的位数,我们先构建了next数组。数组下标是模式串前缀子串结尾字符下标,值是最长可匹配前缀串结尾字符下标。计算next为了效率使用递归的思想。转载 2020-05-22 16:52:49 · 158 阅读 · 0 评论 -
BM算法
BM 算法包含两部分,分别是坏字符规则(bad character rule)和好后缀规则(good suffix shift)。坏字符规则BM 算法的匹配顺序是按照模式串下标从大到小的顺序,倒着匹配的。我们从模式串的末尾往前倒着匹配,当我们发现某个字符没法匹配的时候。我们把这个没有匹配的字符叫作坏字符(主串中的字符)。我们拿坏字符 c 在模式串中查找,发现模式串中并不存在这个字符,也就是说,字符 c 与模式串中的任何字符都不可能匹配。这个时候,我们可以将模式串直接往后滑动三位,将模式串滑动到转载 2020-05-22 12:28:24 · 444 阅读 · 1 评论 -
图
图中有几个概念:无向图、有向图、带权图、顶点、边、度、入度、出度。还学习了图的两个主要的存储方式:邻接矩阵和邻接表。邻接矩阵:邻接矩阵的底层依赖一个二维数组。对于无向图来说,如果顶点 i 与顶点 j 之间有边,我们就将 A[i][j]和 A[j][i]标记为 1;对于有向图来说,如果顶点 i 到顶点 j 之间,有一条箭头从顶点 i 指向顶点 j 的边,那我们就将 A[i][j]标记为 1。同理,如果有一条箭头从顶点 j 指向顶点 i 的边,我们就将 A[j][i]标记为 1。对于带权图,数组中就存储相应转载 2020-05-21 18:18:31 · 122 阅读 · 0 评论 -
数组
/** * 1) 数组的插入、删除、按照下标随机访问操作; * 2)数组中的数据是int类型的; * * Author: leo */type Array struct { data []int length uint}//为数组初始化内存func NewArray(capacity uint) *Array { if capacity == 0 { retur...转载 2020-05-15 16:35:12 · 114 阅读 · 0 评论 -
堆
满足这两点,它就是一个堆:堆是一个完全二叉树;堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值。从图中我们可以看到,数组中下标为 i 的节点的左子节点,就是下标为 i∗2 的节点,右子节点就是下标为 i∗2+1 的节点,父节点就是下标为 2i 的节点。往堆中插入一个元素往堆中插入一个元素后,我们需要继续满足堆的两个特性。就需要进行调整,让其重新满足堆的特性,这个过程我们起了一个名字,就叫作堆化(heapify)。堆化实际上有两种,从下往上和从上往下。这里我先讲从下往上转载 2020-05-15 16:28:10 · 131 阅读 · 0 评论 -
红黑树
因为平衡二叉树的维护成本非常高,如果不维护会导致性能的退化,对于动态数据不太适用,经过取舍,相对牺牲一些性能,减小和降低维护成本,并且经过简单维护保持稳定的性能,所以出现了红黑树。红黑树需要满足这样几个要求:根节点是黑色的;每个叶子节点都是黑色的空节点(NIL),也就是说,叶子节点不存储数据;任何相邻的节点都不能同时为红色,也就是说,红色节点是被黑色节点隔开的;每个节点,从该节点到达其可达叶子节点的所有路径,都包含相同数目的黑色节点;红黑树只是做到了近似平衡,并不是严格的平衡,所以在维护平衡转载 2020-05-14 11:45:13 · 220 阅读 · 0 评论 -
清晰理解红黑树的演变---红黑的含义
前言红黑树,对不少人来说是个比较头疼的名字,在网上搜资料也很少有讲清楚其演变来源的,多数一上来就给你来五条定义,红啊黑啊与根节点距离相等之类的,然后就开始进行旋转、插入、删除这些操作。一通操作下来,连红色和黑色怎么来的,是什么含义,有什么作用都云里雾里的,能搞清楚就怪了。本文介绍红黑树,暂时不涉及任何代码,只是帮助你理解红黑树的演变来源,树结构中红黑色具体含义,保证你理解了过后,再去看什么旋转插入的东西,要清晰得多。换句话说,理解本文要描述的内容是从代码级理解红黑树的基础。开始之前,我还是恳请你保持耐转载 2020-05-13 18:23:11 · 234 阅读 · 0 评论 -
二叉查找树
二叉查找树要求,在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值。二叉查找树的查找操作先取根节点,如果它等于我们要查找的数据,那就返回。如果要查找的数据比根节点的值小,那就在左子树中递归查找;如果要查找的数据比根节点的值大,那就在右子树中递归查找。二叉查找树的插入操作新插入的数据一般都是在叶子节点上,所以我们只需要从根节点开始,依次比较要插入的数据和节点的大小关系。如果要插入的数据比节点的数据大,并且节点的右子树为空,就将新数据直接插到右子节转载 2020-05-13 17:59:02 · 297 阅读 · 0 评论 -
二叉树
树的几个概念:父节点、子节点、兄弟节点、根节点、叶子节点(叶节点)、高度、深度、层。A 节点就是 B 节点的父节点,B 节点是 A 节点的子节点。B、C、D 这三个节点的父节点是同一个节点,所以它们之间互称为兄弟节点。我们把没有父节点的节点叫作根节点,也就是图中的节点 E。我们把没有子节点的节点叫作叶子节点或者叶节点,比如图中的 G、H、I、J、K、L 都是叶子节点。二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子节点和右子节点。除了叶子节点之外,每个节点都有左右两个子节点,这转载 2020-05-13 14:38:32 · 211 阅读 · 0 评论 -
散列表 哈希表 HaskTable
散列表用的是数组支持按照下标随机访问数据的特性,所以散列表其实就是数组的一种扩展,由数组演化而来。可以说,如果没有数组,就没有散列表。我们通过散列函数把元素的键值映射为下标,然后将数据存储在数组中对应下标的位置。当我们按照键值查询元素时,我们用同样的散列函数,将键值转化数组下标,从对应的数组下标的位置取数据。散列函数,顾名思义,它是一个函数。我们可以把它定义成 hash(key),其中 key 表示元素的键值,hash(key) 的值表示经过散列函数计算得到的散列值。散列函数设计的基本要求:1.散列函转载 2020-05-12 19:04:30 · 687 阅读 · 0 评论 -
跳表
跳表是一种各方面性能都比较优秀的动态数据结构,可以支持快速的插入、删除、查找操作,写起来也不复杂,甚至可以替代红黑树(Red-black tree)。有序链表加多级索引的结构就是跳表。加索引之后,查找一个结点需要遍历的结点个数减少了,也就是说查找效率提高了。跳表中查询任意数据的时间复杂度就是 O(logn)。跳表的空间复杂度是 O(n)。跳表这个动态数据结构,不仅支持查找操作,还支持动态的...转载 2020-05-07 18:09:06 · 224 阅读 · 0 评论 -
快速排序
快排的思想是这样的:如果要排序数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作为 pivot(分区点)。我们遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间。经过这一步骤之后,数组 p 到 r 之间的数据就被分成了三个部分,前面 p 到 q-1 之间都是小于 pivot 的,中间是 pivo...转载 2020-04-29 18:21:56 · 121 阅读 · 0 评论 -
归并排序
归并排序把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。归并排序使用的就是分治思想。分治,顾名思义,就是分而治之,将一个大问题分解成小的子问题来解决。小的子问题解决了,大问题也就解决了。从我刚才的描述,你有没有感觉到,分治思想跟我们前面讲的递归思想很像。是的,分治算法一般都是用递归来实现的。分治是一种解决问题的处理思想,递归是一种编程...转载 2020-04-29 17:57:30 · 229 阅读 · 0 评论 -
选择排序
选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。首先,选择排序空间复杂度为 O(1),是一种原地排序算法。选择排序的最好情况时间复杂度、最坏情况和平均情况时间复杂度都为 O(n2)。选择排序是一种不稳定的排序算法。从我前面画的那张图中,你可以看出来,选择排序每次都要找剩余未排序元素中的最小值,并和前面...转载 2020-04-29 14:56:51 · 107 阅读 · 0 评论 -
插入排序
首先,我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算法结束。如图所示,要排序的数据是 4,5,6,1,3,2,其中左侧为已排序区间,右侧是未排序区间。插入排序也包含两种操作,一种是...转载 2020-04-29 14:53:58 · 148 阅读 · 0 评论 -
冒泡排序
冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。我用一个例子,带你看下冒泡排序的整个过程。我们要对一组数据 4,5,6,3,2,1,从小到大进行排序。第一次冒泡操作的详细过程就是这样:可以看出,经过一次冒泡操作之后,6 这个元素已...转载 2020-04-29 14:41:40 · 114 阅读 · 0 评论 -
四个数的排列组合问题
主要是学习其中的递归思想下面是JAVA代码实现:public class ArrayCombination { static int[] a = {1, 2, 3}; static int count = 0; public static void main(String[] args) { permutation(0, a.length-1转载 2015-06-03 10:27:44 · 1285 阅读 · 0 评论 -
交换两个变量的值,不使用第三个变量
通常我们的做法是(尤其是在学习阶段):定义一个新的变量,借助它完成交换。代码如下:int a,b;a=10; b=15;int t;t=a; a=b; b=t;这种算法易于理解,特别适合帮助初学者了解计算机程序的特点,是赋值语句的经典应用。在实际软件开发当中,此算法简单明了,不会产生歧义,便于程序员之间的交流,一般情况下碰到交换变量值的问题,都应采用此算法(以下称为标准转载 2015-06-10 23:49:44 · 551 阅读 · 0 评论 -
老鼠走迷宫递归算法
老鼠走迷宫,递归算法转载 2016-03-15 17:42:32 · 2268 阅读 · 0 评论 -
骑士游历算法
骑士游历,算法转载 2016-03-16 15:26:18 · 10070 阅读 · 0 评论 -
八皇后算法
八皇后,算法转载 2016-03-16 18:32:08 · 598 阅读 · 0 评论 -
java实现随机洗牌算法
import java.util.Random;class Card{ public String num; public String suit; Card(String n,String s) { this.num=n; this.suit=s; } public String toString()转载 2016-03-12 17:17:35 · 3041 阅读 · 0 评论 -
汉诺塔的递归算法与解析
汉诺塔的递归算法与解析转载 2016-03-14 18:42:03 · 546 阅读 · 0 评论 -
背包问题1
背包问题很有意思,同时也富有挑战性。首先看一下这个问题的完整描述:问题假定背包的最大容量为W,N件物品,每件物品都有自己的价值和重量,将物品放入背包中使得背包内物品的总价值最大。转载 2014-09-17 14:53:41 · 561 阅读 · 0 评论