数据结构

K:hash的应用场景

我是研究僧i 提交于 2020-02-10 07:25:21
本博文主要用于讲解Hash的应用场景 Hash主要应用于数据结构中和密码学中。 用于数据结构时,主要是为了提高查询的效率,这就对速度比较重视,对抗碰撞不太看中,只要保证hash均匀分布就可以。 在密码学中,hash算法的作用主要是用于消息摘要和签名,换句话说,它主要用于对整个消息的完整性进行校验。 1. 数据结构 使用Hash的数据结构叫做散列表,主要是为了提高查询的效率。也有直接译作哈希表,也叫Hash表, Hash表是一种特殊的数据结构,它同数组、链表以及二叉排序树等相比较有很明显的区别,它能够快速定位到想要查找的记录,而不是与表中存在的记录的关键字进行比较来进行查找。这个源于Hash表设计的特殊性,它采用了函数映射的思想将记录的存储位置与记录的关键字关联起来,从而能够很快速地进行查找。 2.密码学 在密码学中,hash算法的作用主要是用于消息摘要和签名,换句话说,它主要用于对整个消息的完整性进行校验。 举个用于消息摘要例子,银行的数据库中是不能保存用户密码的原文的,只能保存密码的hash值。在这种应用场景里,对于抗碰撞和抗篡改能力要求极高,对速度的要求在其次。一个设计良好的hash算法,其抗碰撞能力是很高的。 需要注意的是,hash算法在密码学中,主要用于信息的摘要和完整性校验,而不是加密。 概括来说,哈希(Hash)是将目标文本转换成具有相同长度的、不可逆的杂凑字符串

线性数据结构案例4 —— 合并两个有序的单链表 合并之后依然有序

我与影子孤独终老i 提交于 2020-02-10 01:38:04
一、介绍 emsp; 我们定义一个新链表然后,将两个链表的元素依次比较,放入比较最小的放到新链表前面。 二、代码 public static Node mergeByOrder(Node l1, Node l2) { if(l1.next == null || l2.next == null) { return l1.next == null ? l2 : l1; } Node newLinkedHead = new Node(0, ""); l1 = l1.next; // 头节点没有数据我们不要 l2 = l2.next; // 头节点没有数据我们不要 Node temp = newLinkedHead; while (l1 != null && l2 != null) { if (l1.no <= l2.no) { temp.next = l1; temp = temp.next; l1 = l1.next; } else { temp.next = l2; temp = temp.next; l2 = l2.next; } } if (l1 == null) { temp.next= l2; // 连接剩余节点 } if (l2 == null) { temp.next= l1; // 连接剩余节点 } return newLinkedHead; } } 来源: https

什么是数组?

倾然丶 夕夏残阳落幕 提交于 2020-02-09 23:34:24
今天要介绍的主角就是- 数组 ,数组也是数据呈线性排列的一种数据结构。与前一节中的 链表 不同,在数组中,访问数据十分简单,而添加和删除数据比较耗工夫。这和 什么是数据结构 那篇文章中讲到的姓名按拼音顺序排列的电话簿类似。 数组 如上就是数组的概念图,Blue、Yellow、Red 作为数据存储在数组中,其中 a 是数组的名字,后面 [] 中的数字表示该数据是数组中的第几个数据,该数字也就是 数组下标,下标从 0 开始计数 ,比如 Red 就是数组 a 的第 2 个数据。 那么 为什么许多编程语言中的数组都从 0 开始编号的呢 ?先别急,可以先自己思考下,将会在文末进行讲解。 从图中可以看出来,数组的数据是按 顺序存储 在内存的连续空间内的。 由于数据是存储在连续空间内的,所以每个数据的内存地址(在内存上的位置)都可以通过数组下标算出,我们也就可以借此直接访问目标数据,也就是 随机访问 。 比如现在我们想要访问 Red,如果是链表的话,只能使用指针就只能从头开始查找,但在数组中,只需要指定 a[2],便能直接访问 Red。 但是,如果想在任意位置上添加或者删除数据,数组的操作就要比链表复杂多了。这里我们尝试将 Green 添加到第 2 个位置上。 首先,在数组的末尾确保需要增加的存储空间。 为了给新数据 Green 腾出位置,要把已有数据一个个移开,首先把 Red 往后移。 然后把

Go语言操作Redis

空扰寡人 提交于 2020-02-09 16:46:53
在项目开发中redis的使用也比较频繁,本文介绍了Go语言如何操作Redis。 Redis介绍 Redis是一个开源的内存数据库,Redis提供了多种不同类型的数据结构,很多业务场景下的问题都可以很自然地映射到这些数据结构上。除此之外,通过复制、持久化和客户端分片等特性,我们可以很方便地将Redis扩展成一个能够包含数百GB数据、每秒处理上百万次请求的系统。 Redis支持的数据结构 Redis支持诸如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、带范围查询的排序集合(sorted sets)、位图(bitmaps)、hyperloglogs、带半径查询和流的地理空间索引等数据结构(geospatial indexes)。 Redis应用场景 缓存系统,减轻主数据库(MySQL)的压力。 计数场景,比如微博、抖音中的关注数和粉丝数。 热门排行榜,需要排序的场景特别适合使用ZSET。 利用LIST可以实现队列的功能。 Redis与Memcached比较 Memcached中的值只支持简单的字符串,Reids支持更丰富的5中数据结构类型。 Redis的性能比Memcached好很多 Redis支持RDB持久化和AOF持久化。 Redis支持master/slave模式。 Go操作Redis 安装 Go语言中使用第三方库 https:/

List、Set、数据结构、Collections

荒凉一梦 提交于 2020-02-09 15:14:03
第一章 数据结构 1.1 数据结构有什么用? 当你用着java里面的容器类很爽的时候,你有没有想过,怎么ArrayList就像一个无限扩充的数组,也好像链表之类的。好用吗?好用,这就是数据结构的用处,只不过你在不知不觉中使用了。 现实世界的存储,我们使用的工具和建模。每种数据结构有自己的优点和缺点,想想如果Google的数据用的是数组的存储,我们还能方便地查询到所需要的数据吗?而算法,在这么多的数据中如何做到最快的插入,查找,删除,也是在追求更快。 我们java是面向对象的语言,就好似自动档轿车,C语言好似手动档吉普。数据结构呢?是变速箱的工作原理。你完全可以不知道变速箱怎样工作,就把自动档的车子从 A点 开到 B点,而且未必就比懂得的人慢。写程序这件事,和开车一样,经验可以起到很大作用,但如果你不知道底层是怎么工作的,就永远只能开车,既不会修车,也不能造车。当然了,数据结构内容比较多,细细的学起来也是相对费功夫的,不可能达到一蹴而就。我们将常见的数据结构:堆栈、队列、数组、链表和红黑树 这几种给大家介绍一下,作为数据结构的入门,了解一下它们的特点即可。 1.2 常见的数据结构 数据存储的常用结构有:栈、队列、数组、链表和红黑树。我们分别来了解一下: 栈 栈 : stack ,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加

编程技能的层次

 ̄綄美尐妖づ 提交于 2020-02-09 10:42:25
程序员的编程技能随着经验的积累,会逐步提高。编程技能可以分为一些层次,这些层次指的程序员设计和编写程序的能力层级。 第0层——非程序员 初学编程者,遇到问题,完全是懵懵懂懂,不知道该怎么编程去解决问题。也就是说,还是门外汉,还不能被称之为程序员。计算机在他面前还是一个神秘的黑匣子。 第1层——基础程序员 学习过一段时间的编程后,接到任务,可以编写程序完成任务。这一层次编写出来的代码,正常情况下是能够工作的,但在实际运行中,碰到一些特殊条件就会出现各类BUG。也就是说,具备了开发Demo软件的能力,但开发的软件真正交付给客户使用,恐怕会被客户骂死。 虽然程序是写好了,但到底为什么它有时能正常工作,有时又不行,程序员自己也不知道。运行中遇到了bug,或者需求改变,需要修改代码或者添加代码,很快程序就变得结构混乱,代码膨胀,bug丛生。很快,就连最初的开发者自己也不愿意接手维护这个程序了。 第2层——数据结构 经过一段时间的编程实践后,程序员会认识到【程序=数据结构+算法】这一古训的含义。他们会使用算法来解决问题。进而他们会认识到,算法本质上是依附于数据结构的,好的数据结构一旦设计出来,那么好的算法也会应运而生。 设计错误的数据结构,不可能生长出好的算法。 第3层——面向对象 再之后,程序员就会领略面向对象程序设计的强大威力。大多数现代编程语言都是支持面向对象的。但并不是说

数据结构(三)——二叉树的相关操作

亡梦爱人 提交于 2020-02-09 03:29:59
前言 这里同样不介绍二叉树的相关概念,毕竟数据结构的基础已经讲过很多了,这里不再赘述。至于一些平衡二叉树,完全二叉树,红黑树,B+树等相关结构,这个已经有很多博客介绍了,这里只是介绍一下二叉树的一些基础操作。 定义 这个应该见过多次 /** * autor:liman * createtime:2020/2/6 * comment:二叉树节点的实现 */ public class TreeNode { public String value ; public TreeNode left ; public TreeNode right ; public TreeNode ( String value ) { this . value = value ; } } 遍历的非递归实现 递归的实现非常简单,估计很多人都会,这里就介绍非递归的遍历实现 基本的遍历操作如下:这里示意的输出一下表示遍历操作 /** * 做遍历的操作。 * * @param node */ public static void doTraverse ( TreeNode node ) { System . out . print ( node . value + " " ) ; } 先序遍历 /** * 非递归实现的先序遍历,这里用到了栈的操作 * * @param root */ public static

数据结构与算法题目集(中文)7-22 堆栈模拟队列 (25分)

跟風遠走 提交于 2020-02-09 03:25:09
1.题目 设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。 所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数: int IsFull(Stack S) :判断堆栈 S 是否已满,返回1或0; int IsEmpty (Stack S ) :判断堆栈 S 是否为空,返回1或0; void Push(Stack S, ElementType item ) :将元素 item 压入堆栈 S ; ElementType Pop(Stack S ) :删除并返回 S 的栈顶元素。 实现队列的操作,即入队 void AddQ(ElementType item) 和出队 ElementType DeleteQ() 。 输入格式: 输入首先给出两个正整数 N1 和 N2 ,表示堆栈 S1 和 S2 的最大容量。随后给出一系列的队列操作: A item 表示将 item 入列(这里假设 item 为整型数字); D 表示出队操作; T 表示输入结束。 输出格式: 对输入中的每个 D 操作,输出相应出队的数字,或者错误信息 ERROR:Empty 。如果入队操作无法执行,也需要输出 ERROR:Full 。每个输出占1行。 输入样例: 3 2 A 1 A 2 A 3 A 4 A 5 D A 6 D A 7 D A 8 D D D D T 输出样例: ERROR:Full 1

什么是数据结构?

心已入冬 提交于 2020-02-09 01:44:04
本篇文章主要来介绍什么是数据结构。 首先让我们来看一张图片: 数据存储于计算机的内存中。内存如上图所示,形似排成 1 列的箱子,1 个箱子里存储 1 个数据。 数据存储于内存时, 决定了数据顺序和位置关系的便是数据结构 。 其实在我们生活中用到很多数据结构的知识,那么举一个我们生活中的栗子: 首先举一个从上往下顺序添加举个简单的例子。假设我们有1个电话簿——虽说现在很多人都把电话号码存在手机里,但是这里我们考虑使用纸质电话簿的情况——每当我们得到了新的电话号码,就按从上往下的顺序把它们记在电话簿上。 假设此时我们想给张飞打电话,但是因为数据都是按获取顺序排列的,所以我们并不知道张飞的号码具体在哪里,只能从头一个个往下找(虽说也可以从后往前找或者随机查找,但是效率并不会比从上往下找高)。如果电话簿上号码不多的话很快就能找到,但如果存了500个号码,找起来就不那么容易了。 再比如我们可以按姓名的拼音顺序对电话簿进行排列,接下来,试试以联系人姓名的拼音顺序排列吧。因为数据都是以字典顺序排列的,所以它们是有结构的。 使用这种方式给联系人排序的话,想要找到目标人物就轻松多了。通过姓名的拼音首字母就能推测出该数据的大致位置。 那么,如何往这个按拼音顺序排列的电话簿里添加数据呢?假设我们认识了新朋友柯南并拿到了他的电话号码,打算把号码记到电话簿中。由于数据按姓名的拼音顺序排列

数据结构-字符串-字典树

吃可爱长大的小学妹 提交于 2020-02-09 01:33:29
数据结构-字符串-字典树 字典树就是著名的 t r i e trie t r i e 树,是未来学很多字符串自动机的必备前置知识。 用处:插入字符串,查找字符串出现次数。 这个数据结构就是一个有根树,根节点编号为 1 1 1 。除了根节点外,每个节点上有一个字母。对于每个节点 x x x , c h [ x ] [ c ] ch[x][c] c h [ x ] [ c ] 表示这个节点的儿子中字符为 c c c 的那个的编号, m k [ x ] mk[x] m k [ x ] 表示插入的字符串中以这个节点为结尾的字符串数。 每当要插入一个字符串 s s s (下标从 1 1 1 开始)时,就从根节点 1 1 1 开始,如果根节点 1 1 1 没有字符为 s [ 1 ] s[1] s [ 1 ] 的子节点,就创造一个那个节点,然后无论那个节点是不是刚被创造出来的,走到那个节点。然后再看那个节点有没有字符为 s [ 2 ] s[2] s [ 2 ] 的子节点,然后如此操作,走到 s [ n ] s[n] s [ n ] (字符串长度为 n n n )时, m k [ mk[ m k [ 单前节点 ] + + ]++ ] + + 。 查找字符串 s s s 时,也从根节点 1 1 1 开始,沿着 c h [ ] [ ] ch[][] c h [ ] [ ] 数组走