数据结构

数据结构&算法

好久不见. 提交于 2020-03-20 22:58:23
3 月,跳不动了?>>> 在分析算法效率时,经常关注以下两种复杂度: (1)最坏情况复杂度:T worst (n) (2)平均复杂度:T avg (n) 易知T avg (n)<=T worst (n) 注:一般分析最坏情况复杂度,因为平均复杂度不容易找 下表能够比较直观的看出各个复杂度的运行时间 1 2 4 8 16 32 C(常函数) 1 1 1 1 1 1 logn 0 1 2 3 4 5 n 1 2 4 8 16 32 nlogn 0 2 8 24 64 160 n 2 1 4 16 64 256 1024 n 3 1 8 64 512 4096 32768 2 n 2 4 16 256 65536 4294967296 n! 1 2 24 40326 2092278988000 26313×10 33 所以一般情况下避免出现后两种复杂度 下图是几种复杂度的增长速度 (图片来自慕课,陈越姥姥那堂课) 复杂度分析的窍门: 若已知T 1 (n) = O(f 1 (n))和T 2 (n) = O(f 2 (n)),则 T 1 (n) + T 2 (n) = max(O(f 1 (n)),O(f 2 (n))) (就是O(f 1 (n))和O(f 2 (n))的最大值) T 1 (n) × T 2 (n) = O(f 1 (n) × f 2 (n)) for循环的T(n) =

排序算法之归并排序

大憨熊 提交于 2020-03-20 22:24:19
3 月,跳不动了?>>> 一、分治法的思想 把复杂的问题分解,再分解,成为很小的问题,解决这些小问题之后合并,再合并。这就是分治法的思想。 通常分治法是递归的。 二、归并排序 归并排序就是利用分治法,把无序的数列拆分成多个子数列,子数列再拆分成多个子数列,直至只子数列只有2个数,然后排序,合并,再排序,在合并。。。直到只剩一个有序的数列。 归并排序算法的核心就是:两个各自有序的数列合并成一个完全有序的数列。这个过程可以说很简单,就是从两个数列开头选出最小的数,放入第三个数列中,然后较小的数的指标后移,继续重复操作。直到其中一个数列全部被放入队列中,此时另一个队列剩下的全部数放入第三个数列。 归并排序的时间复杂度是O(nlgn) 如图所示: 三、Java代码实现 public class MergeSort { public static void main(String[] args) { int a[] = {5,3,2,8,7,6,10,20,30,11,22,33,44,100,60,200}; mergeSort(a, 0, a.length - 1); for (int i : a) { System.out.println(i); } } //递归拆分数列 public static void mergeSort(int[] a, int low, int high)

[翻译]C#数据结构与算法 – 第五章栈与队列(Part 1)

情到浓时终转凉″ 提交于 2020-03-20 03:42:09
第 5 章 栈与队列 以列表组织数据是很自然的方式。之前我们使用Array与ArrayList将数据作为列表组织。虽然这些数据结构帮助我们将数据以一种适合处理的格式组织,但没有一种结构提供了一种真实的抽象来实际地设计与实现问题的解决方案。 栈与队列是两种面向列表数据结构,其提供了易于理解的抽象。栈中的数据添加与移除都是由列表的一端进行,而队列中的数据由列表的一端添加并由列表的另一端移除。栈在编程语言的实现中广泛使用,从表达式评估到函数调用等一切问题。队列用于处理操作系统进程的优先级调用及模拟显示世界中事件的发生,如银行的收银台及大楼中的电梯操作。 C#提供了两个类来使用这两个数据结构:Stack类与Queue类。我们将讨论怎样使用这些类然后看一下本章中一些实际的例子。 栈,栈的实现与STACK 类 栈是最常使用的数据结构,就像我们刚刚提到的那样。我们将栈定义为一个项目的列表,其仅可以由列表的尾部访问,这个尾部我们称为栈的顶部。一个栈的标准模式就像一个自助餐厅的一摞餐盘。盘子总是由一摞的顶部被取走,当洗碗工或服务生把盘子放回时,仍然是放回顶部。栈是一种被称作后进先出(LIFO)的数据结构。 栈操作 栈的两个最主要操作是向栈添加项与由栈中移除项。Push操作向栈中添加一个项,Pop操作由栈中移除一个项。图5.1展示了这些操作。 另一个在栈上完成的主要操作是查看顶部元素

数据结构之AVL树

不羁的心 提交于 2020-03-19 12:05:52
3 月,跳不动了?>>> 平衡二叉查: 平衡二叉树通常指一棵空树或左右两个子树的高度差的绝对值不超过1,并且任意节点的左右子树都是一棵平衡二叉树,即严格的平衡二叉树。平衡二叉树有多种实现方法:AVL树,红黑树,替罪羊树,伸展树,Treap等。 AVL树: 概念: AVL树又称为 高度平衡 的二叉搜索树。它能保持二叉树的高度平衡,尽量降低二叉树的高度,减少树的平均搜索长度。 性质: 左子树和右子树的高度之差绝对值不超过1。 树中的每个左子树和右子树都是AVL树。 每一个节点都有一个平衡因子,任一节点的平衡因子是1、0、-1,平衡因子等于右子树的高度减去左子树的高度。 class AVLNode<T> { T element; AVLNode<T> left; AVLNode<T> right; int height;//记录高度 //构造器 public AVLNode(T theElement) { this(theElement, null, null); element = theElement; } public AVLNode(T theElement, AVLNode<T> left, AVLNode<T> right) { this.element = theElement; this.left = left; this.right = right; this

redis数据结构

我怕爱的太早我们不能终老 提交于 2020-03-19 00:22:28
踩在各个巨人的肩膀上写的,感谢涉及到的各位巨人!!!特别是钱老师(redis深度历险)! redis:web项目中间件、缓解数据库压力、分布式锁等。 Redis 有 5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)。 string ( 字符串) redis的字符串不同于Java的字符串,redis的字符串是动态字符串,类似于Java的ArrayList,采用预分配--减少内存分配的频繁度。 涉及到的命令:     (单key操作)set 、get、del     (批量操作)mget name1 name2 name3;mset name1 boy name2 girl name3 unknown 在此基础上可以设置过期时间;set name 6 value list ( 列表) Redis 的列表相当于 Java 语言里面的 LinkedList,注意它是链表而不是数组。这意味着 list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为 O(n),这点让人非常意外。 当列表弹出了最后一个元素之后,该数据结构自动被删除,内存被回收。 Redis 的列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串塞进 Redis 的列表

B+树索引

ぃ、小莉子 提交于 2020-03-19 00:18:19
结构上 B树中关键字集合分布在整棵树中,叶节点中不包含任何关键字信息,而B+树关键字集合分布在叶子结点中,非叶节点只是叶子结点中关键字的索引; B树中任何一个关键字只出现在一个结点中,而B+树中的关键字必须出现在叶节点中,也可能在非叶结点中重复出现; 性能上(也即为什么说B+树比B树更适合实际应用中 操作系统 的文件索引和 数据库 索引?) 不同于B树只适合随机检索,B+树同时支持随机检索和顺序检索; B+树的磁盘读写代价更低。B+树的内部结点并没有指向关键字具体信息的指针,其内部结点比B树小,盘块能容纳的结点中关键字数量更多,一次性读入内存中可以查找的关键字也就越多,相对的,IO读写次数也就降低了。而IO读写次数是影响索引检索效率的最大因素。 B+树的查询效率更加稳定。B树搜索有可能会在非叶子结点结束,越靠近根节点的记录查找时间越短,只要找到关键字即可确定记录的存在,其性能等价于在关键字全集内做一次二分查找。而在B+树中,顺序检索比较明显,随机检索时,任何关键字的查找都必须走一条从根节点到叶节点的路,所有关键字的查找路径长度相同,导致每一个关键字的查询效率相当。 (数据库索引采用B+树的主要原因是,)B-树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。B+树的叶子节点使用指针顺序连接在一起,只要遍历叶子节点就可以实现整棵树的遍历

数据结构之二叉排序树

心已入冬 提交于 2020-03-18 14:31:18
某厂面试归来,发现自己落伍了!>>> 概念: 二叉搜索树是一种节点值之间具有一定数量级次序的二叉树。对于树中的每个节点: 若其左子树存在,则其左子树中每个节点的值都不大于该节点的值。 若其右子树存在,则其右子树中每个节点的值都不小于该节点的值。 该节点的左右子树都是二叉搜索树。 没有键值相等的节点。 public class BSTree<T extends Comparable<T>> { private BSTNode<T> mRoot; @Data public class BSTNode<T extends Comparable<T>> { T key; BSTNode<T> left; BSTNode<T> right; BSTNode<T> parent; public BSTNode() { super(); } public BSTNode(T key, BSTNode<T> left, BSTNode<T> right, BSTNode<T> parent) { this.key = key; this.left = left; this.right = right; this.parent = parent; } } } 前驱与后继: 前驱:该节点左子树中最大的节点。数值紧挨着小于的值。 public BSTNode<T> predecessor(BSTNode

数据结构

强颜欢笑 提交于 2020-03-18 14:06:20
1. 几个景点算法: 1.  修路问题:最小生成树(加权值)+ 普利姆 2. 最短路径:图+弗洛伊德算法 3. 汉诺塔: 分支的算法 4. 八皇后:回朔法、 5. 丢手帕 : 约瑟夫问题 2. 线性结构 与非线性结构 1.线性结构 :数据元素之间存在一对一的线性关系 顺序存储结构 , 链式存储结构 (数组,队列,链表和栈) 2 . 非线性结构:(二维数组,多维数组,广义表,树结构,图结构) 3. 稀疏数组 因为该数组中记录了很多值是默认值0,记录了很多没有意义的数据 -》 稀疏数组 代码实现原始二维数组与稀疏数组之间的转化 import org.junit.Test; public class XiShuJuZhen { //创建一个原始的二维数组 11*11 @Test public void testArray() { int[][] charArray = new int[11][11]; //0表示没有棋子,1 表示黑子 2表示蓝子 charArray[1][2] = 1; charArray[2][3] = 2; charArray[4][5] = 2; System.out.println("输出原始的二维数组"); for (int[] is : charArray) { for (int is2 : is) { System.out.print("\t"+is2);

sqlite索引的原理

喜你入骨 提交于 2020-03-18 13:59:12
引言 这篇文章 ,里面讲到对于一个41G大小、包含百万条记录的数据库进行查询操作,如果利用了索引,可以把操作耗时从37s降到0.2s。 那么什么是索引呢?利用索引可以加快数据库查询操作的原理是什么呢? 索引的基本原理 数据库提供了一种持久化的数据存储方式,从数据库中查询数据库是一个基本的操作,查询操作的效率是很重要的。 对于查询操作来说,如果被查询的数据已某种方式组织起来,那么查询操作的效率会极大提高。 在数据库中,一条记录会有很多列。如果把这些记录按照列Col1以某种数据结构组织起来,那么列Col2一定是乱序的。 因此,数据库在原始数据之外,维护了满足特定查找算法的数据结构,指向原始数据,称之为 索引 。 举例来说,在下面的图中,数据库有两列Col1、Col2。在存储时,按照列Col1组织各行,比如Col1已二叉树方式组织。如果查找col1中的某一个值,利用二叉树进行二分查找,不需要遍历整个数据库。 这样一来列Col2就是乱序的。为了解决这个问题,为Col2建立了索引,即把Col2也按照某种数据结构(这里是二叉树)组织起来。这样子查找列Col2时只需要进行二分查找即可。  索引的实现 由于数据库是存储在磁盘上的,因此实现索引用的数据结构会存储在磁盘上。磁盘的IO是需要注意的问题。 二叉树 二叉树是一种经典的数据结构,但是并不适合进行数据库索引。

深入理解MySQL索引

做~自己de王妃 提交于 2020-03-18 13:26:59
前言 当提到MySQL数据库的时候,我们的脑海里会想起几个关键字:索引、事务、数据库锁等等,索引是MySQL的灵魂,是平时进行查询时的利器,也是面试中的重中之重。 可能你了解索引的底层是b+树,会加快查询,也会在表中建立索引,但这是远远不够的,这里列举几个索引常见的面试题: 1、索引为什么要用b+树这种数据结构? 2、聚集索引和非聚集索引的区别? 3、索引什么时候会失效,最左匹配原则是什么? 当遇到这些问题的时候,可能会发现自己对索引还是一知半解,今天我们一起学习MySQL的索引。 一、一条查询语句是如何执行的 首先来看在MySQL数据库中,一条查询语句是如何执行的,索引出现在哪个环节,起到了什么作用。 1.1 应用程序发现SQL到服务端 当执行SQL语句时,应用程序会连接到相应的数据库服务器,然后服务器对SQL进行处理。 1.2 查询缓存 接着数据库服务器会先去查询是否有该SQL语句的缓存,key是查询的语句,value是查询的结果。如果你的查询能够直接命中,就会直接从缓存中拿出value来返回客户端。 注:查询不会被解析、不会生成执行计划、不会被执行。 1.3 查询优化处理,生成执行计划 如果没有命中缓存,则开始第三步。 解析SQL:生成解析树,验证关键字如select,where,left join 等)是否正确。 预处理:进一步检查解析树是否合法,如检查数据表和列是否存在