数据结构

Redis(一)基础数据结构

安稳与你 提交于 2020-02-14 05:52:26
1.目录 Redis 基础数据结构 string (字符串) list (列表) hash (字典) set (集合) zset (集合) 容器型数据结构的通用规则 过期时间 2.Redis 基础数据结构 Redis 有 5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集 合)、hash (哈希) 和 zset (有序集合)。 3.string (字符串) 字符串 string 是 Redis 最简单的数据结构。Redis 所有的数据结构都是以唯一 的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据。 不同类型的数据结构的差异就在于 value 的结构不一样。 Redis 的字符串是动态字符串,是可以修改的字符串,内部结构实现上类似于 Java 的 ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配,如图中 所示,内部为当前字符串实际分配的空间 capacity 一般要高于实际字符串长度 len。当字符串长度小于 1M 时,扩容都是加倍现有的空间,如果超过 1M,扩 容时一次只会多扩 1M 的空间。 需要注意的是字符串最大长度为 512M。 4.list (列表) Redis 的列表相当于 Java 语言里面的 LinkedList,注意它是链表而不是数组。 这意味着 list

数据结构与算法(2)

a 夏天 提交于 2020-02-14 01:51:24
1 双向线性链表 2 单向线性链表 1 双向线性链表 1.1 问题 双向线性链表是采用链式存储的方式存储的线性表。链式存储结构是由一系列结点(链表中每一个元素称为结点)组成,每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储当前结点的前驱结点和后继结点地址的指针域,结点是在有数据时动态生成的,是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 1.2 方案 双向线性链表的基本操作包括: 初始化操作,在初始化操作中将双向线性链表的头指针指空。 求表长,求表长操作是计算出双向线性链表中结点的个数。 取双向线性链表中指定位置的结点,即给定双向线性链表中的第几个结点,求其值。 查找结点,在双向线性链表中查找值为x的结点,并返回该结点在双向线性链表中的位置。若双向线性链表中有多个结点的值和x相同,则返回首次找到的结点位;若双向线性链表中没有结点的值为x,则返回一个NULL表示查找失败。 插入结点,在双向线性链表的第i个结点前插入一个值为x的新结点。 删除结点,删除双向线性链表的第i个结点。 1.3 步骤 实现此案例需要按照如下步骤进行。 步骤一:定义双向线性链表 在C语言中: 1)定义一个变量来表示双向线性链表中某个结点的数据。 2)定义两个指针来表示该结点的前驱结点和后继结点的地址。 3

数据库MySQL:B+ Tree

匆匆过客 提交于 2020-02-14 01:27:49
索引 加速查询的数据结构 索引常见数据结构 顺序查找:time: O(n),大数据量此算法效率糟糕。 二叉树查找:time:O(logn),二叉查找树可能不平衡。 hash索引:time:O(1),无法满足范围查找。 红黑树:time:O(h) = O(logn) B Tree B+ Tree 来源: https://www.cnblogs.com/xiaobaizzz/p/12306028.html

数据结构与算法(4)

纵饮孤独 提交于 2020-02-14 01:16:08
1 冒泡排序 2 插入排序 3 选择排序 4 归并排序 5 线性查找 6 二分查找 1 冒泡排序 1.1 问题 冒泡排序是一种著名的排序方法。 冒泡排序的过程是这样的,首先,将待排序的数组中的第一个元素与第二个元素相对比,如果这两个元素的大小顺序不是我们要求的顺序,则将它们交换过来。然后,将待排序的数组中的第二个元素与第三个元素相对比,如果这两个元素的大小顺序也不是我们要求的顺序,则也将它们交换过来。下一步,是对比第三个元素与第四个元素,直至倒数第二个元素与最后一个元素相对比。这样一趟对比下来,小的数据元素会一点一点的往前放,而大的数据元素会一点一点的往后放。反复多趟的这样对比,直到所有数据都排好序为止。 1.2 方案 为了理解冒泡排序算法,我们先假设有一个长度为10的数组,数组内容如图-1所示: 图-4中的数组元素为无序状态,现需要将数组内的元素排序成从小到大的升序状态。可以先进行第一趟比较。首先比较第1个和第2个数,也就是数组第一个元素3和数组第二个元素2,将小数放前,大数放后。交换后如图-2所示: 然后,将图-2中的第2个和第3个数,也就是数组第二个元素3和数组第三个元素4,进行对比,由于3小于4,所以不进行交换。接着将图-2中的第3个和第4个数对比后发现也不需要交换。这样依次进行对比,直到图-2中的第7个和第8个数,也就是数组第七个元素9和数组第八个元素1,对比时

访问者模式

强颜欢笑 提交于 2020-02-14 00:55:31
一、概述 一般问题: 对象结构比较稳定,但经常需要在此对象结构上定义新的操作。 核心方案: 封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。 设计意图: 一般情况下,一个类会封装一些属性,同时会提供访问这些属性的方法。如果这个类的属性是稳定的,但是访问属性的接口却经常变动,也就是经常需要修改类代码,显然不符合“开闭原则”。在设计模式里,没有什么是不能拆的,既然数据结构稳定,数据操作经常改变,那就把数据操作封装到单独的类中好了,然后再在这些类中定义好对每种数据类型的访问方法,这就是最初的访问者模式了。 访问者模式的类图在众多设计模式里属于比较复杂的。我们分成两部分来看: (1)数据结构端 Element定义元素类,是所有数据类型的抽象类,需要定义accept接口,用来接受访问者。 ObjectStructure为元素类容器 (2)数据访问端 Visitor定义访问者类,是所有访问者的抽象类,需要定义各个元素的visite接口,用于对不同元素的区别对待 二、应用实战 实际开发中用到访问者模式的地方很少,没有必要无中生有一个故事,硬套上设计模式。Java新特性——注解——其解析原理的确用到了访问者模式。编译时Annotation解析的基本原理是:在某些代码元素上(如类型,函数,字段等)添加注解

数据结构和算法(6)之单向环形链表与约瑟夫问题

不想你离开。 提交于 2020-02-13 22:02:24
学习数据结构和算法的日常Demo 单向环形链表 代码实现: // 创建环形单向列表 class CircleSingleLinkedList { // 创建first节点 private NNode first = null ; private int nums ; public CircleSingleLinkedList ( int nums ) { this . nums = nums ; } // 添加节点,构建环形链表 public void addNode ( ) { // nums为传入的节点数 if ( nums < 1 ) { System . out . println ( "节点数不能少于1!" ) ; return ; } // 辅助指针 NNode cur = null ; // 循环创建环形链表 for ( int i = 1 ; i <= nums ; i ++ ) { NNode node = new NNode ( i ) ; // 如果是第一个节点(环的起始) if ( i == 1 ) { first = node ; // 起始为1 first . setNext ( first ) ; // 自成环 cur = first ; // 让cur指向第一个节点 node = null ; // 避免内存泄漏 } else { cur .

Java数据结构——归并排序

我怕爱的太早我们不能终老 提交于 2020-02-13 17:35:20
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序是一种稳定的排序方法。 比如初始数组:[3,5,6,7,8,4,1,2] ①分成了两个大小相等的子数组:[3,5,6,7],[8,4,1,2] ②再划分成了四个大小相等的子数组:[3,5],[6,7],[8,4],[1,2] ③此时,left < right 还是成立,再分:[3],[5],[6],[7],[8],[4],[1],[2] 此时,每个数组中的left == right,再根据递归的策略,每两个进行归并: merge([3],[5]) 得到 [3,5] merge([6],[7]) 得到[6,7] merge([3],[5],[6],[7]) 得到[3,5,6,7] 最终得到 有序数组。 import java.util.Arrays; import java.util.Date; public class Main { public static void main(String[] args) { int[] arr = new int[10]; int[] temp = new

数据结构与算法整理3——BP算法和KMP算法

核能气质少年 提交于 2020-02-13 17:12:01
数据结构与算法整理3——BP算法和KMP算法 目录 数据结构与算法整理3——BP算法和KMP算法 1、字符串的基本操作 2、模式匹配——BP算法和KMP算法 3、串的操作代码(C语言) 1、字符串的基本操作 1)串的定义:字符串(也就是串)是0个或多个字符序列组成的有限序列。 串就是数据元素为单个字符的特殊线性表。 “qhjkdcbjsb”(隐含结束符\0)就是一个字符串,引号起界定作用,“”表示空串,串长为0 “ ”空格串不是空串,串长为空格数。 2)串的存储类型: 顺序存储 :定长顺序存储结构、堆分配存储结构(动态分配连续内存) 链式存储: 2、模式匹配——BP算法和KMP算法 串的模式匹配:就是指定一个主串S和子串T,求T在S中第一次出现的位置。 (1) 朴素模式匹配(BP算法) 核心思想 :主串S和子串T,S[1]和T[1]比较,S[2]与T[2]比较,直到S[n]与T[n]都是相等的为止,若S[i]与T[i]不相等,则子串向右移动一个(一个字符)继续比较。 时间复杂度 :主串S长度为n,子串T长度为m,最多进行m(m-n+1)次,最坏的时间复杂度为O(mn) 效率不高。 (2) KMP 算法 核心思想 :尽量利用已经得到的“部分匹配”的结果信息,不要让i回溯,加快子串右滑的速度, 问题由子串决定而不是主串决定的 next 数组 :是一个智能数组

数据结构之链表

半世苍凉 提交于 2020-02-13 14:10:50
一、定义--离散存储【链表】 n个节点离散分配;彼此通过指针相连;每个节点只有一个前驱节点, 每个节点只有一个后续节点;首节点没有前驱节点,尾节点没有后续节点。 二、 专业术语: 首节点:第一个有效节点 尾节点:最后一个有效节点 头节点:第一个有效节点前面的那个节点;头节点不存放有效数据; 加上头节点是为了方便对链表的操作 头指针:指向头节点的指针变量 尾指针:指向尾节点的指针变量 三、分类:单链表;双链表;循环链表;非循环链表 四、代码 #include<stdio.h> #include<malloc.h> #include<stdlib.h> typedef struct node{ int data; //数据域 struct node * pNext; //指针域 }NODE,* PNODE; //NODE等价于struct node;PNODE等价于 struct node * PNODE init_link(void); void traverse_link(PNODE pHead); bool is_empty(PNODE pHead); int length_link(PNODE pHead); bool insert_link(PNODE pHead,int pos,int val); bool del_link(PNODE pHead,int pos,int

数据结构之链表定义及基本操作实现

对着背影说爱祢 提交于 2020-02-13 14:06:30
  在我上一篇的博客中说过,数据结构的线性结构中有连续存储结构和离散存储结构,这次就写一写学习离散存储结构——链表的小总结。   首先说一下链表的定义:链表是物理存储单元上非连续、非顺序的存储结构,链表的结点间通过指针相连,每个结点只对应有一个前驱结点和一个后继结点,其中,首结点没有前驱结点,尾节点没有后继结点。上述表述共同构成了对链表的定义。   接下来说一下链表的结构:链表由头结点+有效节点构成,其中有效节点由分为首结点、普通节点、尾节点。 头结点:链表中有效结点前面的结点,头结点并不存放实际数据,仅仅是为了方便对链表的操作。 头指针:头结点并没有什么实际的含义,仅仅是为了方便对链表的操作,而头指针,顾名思义,就是指向头结点的指针。我们通过头指针指向的头结点的指针域对链表进行操作。 首结点:链表的第一个有效的结点。 尾结点:链表中最后一个有效的结点,尾结点的指针域为空。   链表已经学习完毕,那么接下来就是要说一下链表的构成——结点。因为链表是一张离散存储的结构,所以就需要通过地址去访问,那么久需要在结点中保存下一个结点的地址。还是用到c语言中的结构体。 1 //定义链表的节点 2 typedef struct Node{ 3 //数据域 4 int data; 5 //指针域 6 struct Node * pNext; 7 }NODE,*PNODE;   结点定义完毕后