350 likes | 515 Views
队、栈、哈希表. 2010 赛前知识点梳理. 数据结构 ( Data Structure ) 一般包括以下三方面内容: ①数据元素及其关系在计算机存储器内的表示,称为 数据的存储结构 ( Storage Structure ); ② 数据的逻辑结构 ( Logical Structure ); ③ 数据的运算 ,即对数据施加的操作。 数据的运算定义在 数据的逻辑结构 上,每种逻辑结构都有一个运算的集合。最常用的 检索、插入、删除、更新、排序 等运算实际上只是在抽象的数据上所施加的一系列抽象的操作。 . 存储结构.
E N D
队、栈、哈希表 2010赛前知识点梳理
数据结构(Data Structure) 一般包括以下三方面内容: ①数据元素及其关系在计算机存储器内的表示,称为数据的存储结构(Storage Structure); ② 数据的逻辑结构(Logical Structure); ③ 数据的运算,即对数据施加的操作。 数据的运算定义在数据的逻辑结构上,每种逻辑结构都有一个运算的集合。最常用的检索、插入、删除、更新、排序等运算实际上只是在抽象的数据上所施加的一系列抽象的操作。
存储结构 也叫物理学结构,是数据的逻辑结构在计算机中的存储方式。它不仅要实现数据元素本身的存储还要实现 数据之间逻辑关系的存储。 方法主要有顺序与链式。
数据的逻辑结构分类 (1)线性结构 线性结构的逻辑特征是:若结构是非空集,则有且仅有一个开始结点和一个终端结点,并且所有结点都最多只有一个直接前趋和一个直接后继。 线性表是一个典型的线性结构。数组、栈、队列、串等都是线性结构。 (2)非线性结构 非线性结构的逻辑特征是:一个结点可能有多个直接前趋和直接后继。数组、广义表、树和图等数据结构都是非线性结构。
一个算法应该具有以下五个重要的特征: 1、有穷性: 一个算法必须保证执行有限步之后结束; 2、确切性: 算法的每一步骤必须有确切的定义; 3、输入:一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定除了初始条件; 4、输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的; 5、可行性: 算法原则上能够精确地运行,而且人们用笔和纸做有限次运算后即可完成。
R(队尾) 顺序队:队列的顺序存储表示。用一组地址连续的存储单元(Q[m])依次存放从队列头到队列尾的元素,指针front和rear分别指示队头元素和队尾元素的位置。 入队,尾指针增1,rear = rear + 1, 出队,头指针增1, front = front + 1, 因此,在非空队列中,头指针始终指向队头元素,而尾指针始终指向队尾元素的下一个位置。 队空: front = rear 队满:rear=m时再进队将溢出(假溢出) 解决办法:将顺序队列改造为一个头尾相接的环状的空间,形成循环(环形)队列。 从队尾放元素,然后移动指针,也就是每次它指向的是现有内容的下一个空间 F(队首)
C D front rear A,B出队 队列的进队和出队: A B C D rear front 空队列 front rear A,B,C, D进队 C D E F G front rear E,F,G进队 C D E F G 产生假溢出原因:被删除元素的空间在该元素删除后永远用不到。 rear front H进队,溢出
6 7 Maxsize-1 5 0 rear 4 1 3 2 front 循环队列 循环队列 (Circular Queue) 队头、队尾指针加1,可用取模(余数)运算实现。 队头指针进1: front = (front+1) mod maxsize; 队尾指针进1: rear = (rear+1) mod maxsize; 队列初始化:front = rear = 0; 队空条件:front == rear; 队满条件:(rear+1) mod maxsize == front;
6 7 rear 6 7 front front 5 5 0 A 0 B 4 1 4 1 D C rear 3 2 2 3 空队列 一般情况 rear 6 7 rear 6 7 C G H front C G front 5 5 F F 0 0 A A E B E B 4 1 4 1 D C D C 3 2 3 2 队满 队满(正确) 在循环队列中,永远会空一个位置,是为了辨别队满还是队空。所以Q[m]有m个分量,只能表示长度不超过m的队列。
历届初比赛题(选) • (9tg)已知队列(13,2,11,34,4l,77,5,7,18,26,15),第一个进入队列的元素是13,则第五个出队列的元素是( )。 A)5 B)41 C)77 D)13 E)18 B
栈(stack)。 • 栈是一种特殊的线性表,对它的插入和删除都限制在表的同一端进行。 递归中应用栈保留中间变量
进栈 a5 出栈 栈顶 栈底 一、栈的概念和特性 • 把可以操作的一端称为栈顶,不允许操作的一端称为栈底。在栈顶插入一个元素,称为进栈,在栈顶删除一个元素称为出栈。 • 栈中元素的进出是按后进先出的原则进行,这是栈结构的重要特征。 • (LIFO:Last In First Out) • 用一个变量记录栈顶的位置,通常称这个变量为栈指针。
练习4.1 • 设栈S的初始状态为空,现有5个元素组成的序列{1,2,3,4,5},对该序列在S 栈上依次进行如下操作(从序列中的1开始,出栈后不再进栈):进栈,进栈,进栈,出栈,进栈,出栈,进栈,问: • 出栈的元素序列是:_________, • 栈顶指针的值为______, • 栈顶元素为:______________。 解答: 出栈序列为{3,4}, 栈顶指针值为3, 栈顶元素为5。 1 2 3 4 5 3 4
练习4.2 • 设栈S初始状态为空,元素e 1 ,e 2 ,e 3 ,e 4 ,e 5 ,e 6依次通过栈S,若出栈后的输出顺序为e 2 ,e 4 ,e 3 ,e 6 ,e 5 ,e 1 ,则栈S的容量至少应该为( )。 • A)2 B)3 C)4 D)5 e 1 e 2 e 3 e 5 e 6 e 4 e 2 e 4 e 3 e 6 e 5 e 1
练习4.3 • 若已知一个栈的入栈顺序是1,2,3,……,n,其输出序列为P1,P2,P3,……,Pn,若P1是n,则Pi是( )。 • A)i B)n-1 C)n-i+1 D)不确定 【分析】 1, 2, 3,……, n P1,P2,P3,……,Pn 已知 p1=n,说明所有的元素进栈以后,才开始出栈。所以p2=n-1,pi=n-i+1。
历届初比赛题(选) • (8tg)设栈S和队列Q的初始状态为空,元素e1,e2,e3,e4,e5,e6依次通过钱S,一个元素出栈后即进入队列Q,若出队的顺序为e2,e4,e3,e6,e5,e1,则钱S的容量至少应该为( ) 。A) 2 B) 3 C) 4 D) 5 • (9tg_多项)已知元素(8,25,14,87,5l,90,6,19,20),问这些元素以怎样的顺序进入栈,才能使出栈的顺序满足:8在5l前面;90在87后面;20在14后面;25在6前面;19在90后面。 ( ) • A)20,6,8,51,90,25,14,19,87 • B)51,6,19,20,14,8,87,90,25 • C)19,20,90,7,6,25,5l,14,87 • D)6,25,51,8,20,19,90,87,14 • E)25,6,8,51,87,90,19,14,20 • (13tg)地面上有标号为A、B、C的三根柱,在A柱上放有10个直径相同中间有孔的圆盘,从上到下依次编号为1,2,3……,将A柱上的部分盘子经过B柱移入C柱,也可以在B柱上暂存。如果B柱上的操作记录为“进、进、出、进、进、出、出、进、进、出、进、出、出”。那么,在C柱上,从下到上的编号为( )。 • A.2 4 3 6 5 7 B.2 4 1 2 5 7 C.2 4 3 1 7 6 D.2 4 3 6 7 5 B D D
(11tg_多项)设栈S的初始状态为空,元素a, b, c, d, e, f, g依次入栈,以下出栈序列不可能出现的有( )。 • A. a, b, c, e, d, f, g B. b, c, a, f, e, g, d C. a, e, c, b, d, f, g • D. d, c, f, e, b, a, g E. g, e, f, d, c, b, a • (12tg_多项)设栈S的初始状态为空,元素a, b, c, d, e 依次入栈,以下出栈序列不可能出现的有( )。 • A. a, b, c, e, d B. b, c, a, e, d • C. a, e, c, b, d D. d, c, e, b, a • (12tg ) 某个车站呈狭长形,宽度只能容下一台车,并且只有一个出入口。已知某时刻该车站状态为空,从这一时刻开始的出入记录为:“进,出,进,进,进,出,出,进,进,进,出,出”。假设车辆入站的顺序为1,2,3,……,则车辆出站的顺序为( )。 A. 1, 2, 3, 4, 5 B. 1, 2, 4, 5, 7 C. 1, 4, 3, 7, 6 D. 1, 4, 3, 7, 2 E. 1, 4, 3, 7, 5 C E C C 有一定规律,分段有序
哈希表 1、概念2、构造3、冲突解决办法
哈希表(散列查找 ) 一 基本概念 散列查找,也称为哈希查找。它既是一种查找方法,又是一种存贮方法,称为散列存贮。散列存贮的内存存放形式也称为哈希表或散列表。 散列查找,与以前介绍的查找方法完全不同,前面介绍的所有查找都是基于待查关键字与表中元素进行比较而实现的查找方法,而散列查找是通过构造哈希函数来得到待查关键字的地址,按理论分析真正不需要用到比较的一种查找方法。 例如,要找关键字为k的元素,则只需求出函数值H(k),H(k)为给定的哈希函数,代表关键字k在存贮区中的地址,而存贮区为一块连续的内存单元,可用一个一维数组(或链表)来表示。
哈希表的概念及作用 • 一般的线性表,树中,记录在结构中的相对位置是随机的,即和记录的关键字之间不存在确定的关系,因此,在结构中查找记录时需进行一系列和关键字的比较。这一类查找方法建立在“比较“的基础上,查找的效率依赖于查找过程中所进行的比较次数。 • 理想的情况是能直接找到需要的记录,因此必须在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和结构中一个唯一的存储位置相对应。
哈希表最常见的例子是以学生学号为关键字的成绩表,1号学生的记录位置在第一条,10号学生的记录位置在第10条...哈希表最常见的例子是以学生学号为关键字的成绩表,1号学生的记录位置在第一条,10号学生的记录位置在第10条... 如果不连续会浪费很多 如果我们以学生姓名为关键字,如何建立查找表,使得根据姓名可以直接找到相应记录呢? 如果两个同学分别叫 刘丽 刘兰 该如何处理这两条记录? 这个问题是哈希表不可避免的,即冲突现象
1.直接定址法 可表示为H(k)=a.k+b,其中a、b均为常数。 这种方法计算特别简单,并且不会发生冲突,但当关键字分布不连续时,会出现很多空闲单元,将造成大量存贮单元的浪费。如学号 h(k)=k 2.数字分析法 对关键字序列进行分析,取那些位上数字变化多的、频率大的作为哈希函数地址。 二、 哈希函数的构造 哈希函数的构造目标是使哈希地址尽可能均匀地分布在散列空间上,同时使计算尽可能简单,冲突次数少。具体常用的构造方法有如下几种:
例如,对如下的关键字序列: 9 9 3 4 6 5 3 2 9 9 3 7 2 2 4 2 9 9 3 8 7 4 3 3 9 9 3 0 1 3 6 7 9 9 3 2 2 8 1 7 9 9 3 3 8 9 6 7 9 9 3 5 4 1 5 7 9 9 3 6 8 5 3 7 9 9 3 6 8 5 3 2 ...... 通过对上述关键字序列分析,发现前3位相同,第8位只可取2、3、7,因此,这四位不可取。中间的四位的数字变化多些,可看成是随机的,若规定地址取3位,则哈希函数可取它的第4、5、6位。于是有: H(99346532)=465 H(99372242)=722 H(99387433)=874 H(99301367)=016 H(99322817 )=228
3.平方取中法 取关键字平方后的中间几位为哈希函数地址。这是一种比较常用的哈希函数构造方法,但在选定哈希函数时不一定知道关键字的全部信息,取其中哪几位也不一定合适,而一个数平方后的中间几位数和数的每一位都相关,因此,可以使用随机分布的关键字得到哈希函数地址。 2 关键字 (关键字) 函数地址 010 0100 0 010 000 1100 1 210 000 210 1200 1 440 000 440 1160 1 370 400 370 2061 4 310 541 310 利用平方取中法得到散列函数地址 如图中,随机给出一些关键字,并取平方后的第2到4位为函数地址。
4.折叠法 将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位)作为哈希函数地址,称为折叠法。 例如,假设关键字为某人身份证号码430104681015355,则可以用4位为一组进行叠加,即有5355+8101+1046+430=14932,舍去高位,则有H(430104681015355)=4932为该身份证关键字的哈希函数地址。 5.除留余数法 该方法是用关键字序列中的关键字k除以一个整数p所得余数作为哈希函数的地址,即 H(k)=k%p 。 P<=m m为哈希表长度
除留余数法计算简单,适用范围广,是一种最常使用的方法。这种方法的关键是选取较理想的p值,使得每一个关键字通过该函数转换后映射到散列空间上任一地址的概率都相等,从而尽可能减少发生冲突的可能性。一般情形下,p 取为一个素数较理想,并且要求装填因子α最好是在0.6∽0.9之间,所以p 最好取1.1n∽1.7n之间的一个素数较好,其中n为哈希表中待装元素个数。 6. 随机法 选择一个随机函数,取关键值的随机函数值为它的哈希地址,即 H(key)=random(key) random()不能是一般的随机函数,固定的参数必须返回确定的值。
三、解决冲突的方法 由于哈希存贮中选取的哈希函数不是线性函数,将大的关键值的取值空间映射到小的地址空间中,故不可避免地会产生冲突,下面给出常见的解决冲突方法。 1.开放定址法 开放定址法就是从发生冲突的那个单元开始,按照一定的次序,从哈希表中找出一个空闲的存储单元,把发生冲突的待插入关键字存储到该单元中,从而解决冲突的发生。在哈希表未满时,处理冲突需要的“下一个”空地址在哈希表中解决。 开放定址法利用下列公式求“下一个”空地址 Hi=(H(key)+di) MOD m i=1,2,…K(K<=m-1) 其中H(key)为哈希函数,m为哈希表长度,di为增量序列 增量 di 有三种取法: (1) 线性探测再散列:di = ci。最简单的情况 c=1 (2) 平方探测再散列:di = 12, -12, 22, -22, …, (3) 随机探测再散列:di 是一组伪随机数列
Hi=(H(key)+di) MOD m 设有哈希函数H(key) = key mod 7,哈希表的地址空间为0~6,对关键字序列(32,13,49,55,22,38,21)按线性探测再散列和二次探测再散列的方法分别构造哈希表。解:(1)线性探测再散列:32 % 7 = 4 ; 13 % 7 = 6 ; 49 % 7 = 0 ; 55 % 7 = 6 发生冲突,下一个存储地址(6+1)% 7 = 0,仍然发生冲突,再下一个存储地址:(6+2)% 7 = 1 未发生冲突,可以存入。22 % 7 = 1 发生冲突,下一个存储地址是:(1+1)% 7 = 2 未发生冲突;38 % 7 = 3;21 % 7 = 0 发生冲突,按照上面方法继续探测直至空间5,不发生冲突,所得到的哈希表对应存储位置: 对于利用开放地址法处理冲突所产生的哈希表中删除一个元素时需要谨慎,不能直接地删除,因为这样将会截断其他具有相同哈希地址的元素的查找地址,所以,通常采用设定一个特殊的标志以示该元素已被删除。
7 8 9 10 0 6 5 11 1 12 2 4 3 14 1 68 27 79 19 20 84 55 23 11 10 用线性探查建立的哈希表 (1)线性探查法 例: 给定关键字序列为19,14,23,1,68,20,84,27,55,11,10,79,哈希函数H(k)=k%13 ,哈希表空间地址为0∽12,试用线性探查法建立哈希存贮(哈希表)结构。 得到的哈希表如下图所示
2. 链地址法 链地址法也称拉链法,是把相互发生冲突的同义词用一个单链表链接起来,若干组同义词可以组成若干个单链表 例:对给定的关键字序列19,14,23,1,68,20,84,27,55,11,10,79,给定哈希函数为H(k)=k%13,试用拉链法解决冲突建立哈希表。
0 ^ 79 ^ 27 1 14 1 2 ^ 3 55 68 ^ 4 ^ 5 ^ 6 84 ^ 19 7 20 ^ 8 ^ 9 ^ 10 10 ^ 23 11 11 ^ 12 ^ 拉链法解决冲突的散列表
(8tg ) 设有一个含有13个元素的Hash表(O~12),Hash函数是:H(key)=key % 13,其中%是求余数运算。用线性探查法解决冲突,则对于序列(2、8、31、20、19、18、53、27),18应放在第几号格中( ) 。A) 5 B) 9 C) 4 D) 0 3、使1 -8号格字的访问顺序为:8、2、6、5、7、3、1、4,则下图中的空格中应填入( )。 A)6 B)0 C)5 D)3 某空间中存放的是下一个空间的地址 8 2 6 nil 2 6 -1
2009.dx8、散列表的地址区间为0-10,散列函数为H(K)=K mod 11。采用开地址法的线性探查法处理冲突,并将关键字序列26,25,72,38,8,18,59存储到散列表中,这些元素存入散列表的顺序并不确定。假定之前散列表为空,则元素59存放在散列表中的可能地址有: A) 5 B) 7 C) 9 D) 10 26,25,72,38,8,18,59 0 1 2 3 4 5 6 7 8 9 10 A.按26,59顺序存储,则59放到5 B.按38,72,59顺序存储,则59放到7 C.按26,38,72,18,8,59顺序存储,则59放到9 D.因为25放到3,不会对其他数据产生影响,其余5个数据(不算59),最多只能占去4,5,6,7,8五个位置,所以59不可能放到10 4 3 6 5 8 6 4
0 1 2 3 4 5 6 7 8 9 10 60 17 29 例:表长为11的哈希表中已填有关键字为17,60,29的记录, 哈希函数为 H(key)=key MOD 11。现有第4个记录,其关键字为38, 按三种处理冲突的方法,将它填入哈希表中。 38 38 38 (1) H(38)=38 MOD 11=5 冲突 H1=(5+1) MOD 11=6 冲突 H2=(5+2) MOD 11=7 冲突 H3=(5+3) MOD 11=8 不冲突 (2) H(38)=38 MOD 11=5 冲突 H1=(5+1²) MOD 11=6 冲突 H2=(5-1²) MOD 11=4 不冲突 (3) H(38)=38 MOD 11=5 冲突 设伪随机数序列为9,则: H1=(5+9) MOD 11=3 不冲突 Hi = (H(key) + di) MOD m
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 例:已知一组关键字 ( 19, 14, 23, 1, 68, 20, 84, 27, 55, 11, 10, 79 ) 哈希函数为 H(key) = key MOD 13, 哈希表长为m=16, 设每个记录的查找概率相等,计算ASL。 (1) 用线性探测再散列处理冲突,即Hi=(H(key)+di) MOD m 14 20 84 11 1 55 19 79 23 68 27 10 H(55)=55 mod 13= 3 冲突 H1=(3+1) mod 16 = 4 冲突 H2=(3+2) mod 16 = 5 解:(1)用线性探测再散列处理冲突 H(19)=19 mod 13 = 6 H(14)=14 mod 13 = 1 H(11)=11 mod 13 = 11 H(23)=23 mod 13 = 10 H(10)=10 mod 13 = 10 冲突 H1=(10+1) mod 16 = 11 冲突 H2=(10+2) mod 16 = 12 H(1)=1 mod 13 = 1 冲突 H1=(1+1) mod16 = 2 H(68)=68 mod 13 = 3 H(79)=70 mod 13 = 1 冲突 H1=(1+1) mod 16 = 2 冲突 H2=(1+2) mod 16 = 3 冲突 H3=(1+3) mod 16 = 4 冲突 H4=(1+4) mod 16 = 5 冲突 H5=(1+5) mod 16 = 6 冲突 H6=(1+6) mod 16 = 7 冲突 H7=(1+7) mod 16 = 8 冲突 H8=(1+8) mod 16 = 9 H(20)=20 mod 13 = 7 H(84)=84 mod 13 = 6 冲突 H1=(6+1) mod 16 = 7 冲突 H2=(6+2) mod 16 = 8 H(27)=27 mod 13 = 1 冲突 H1=(1+1) mod 16 = 2 冲突 H2=(1+2) mod 16 = 3 冲突 H3=(1+3) mod 16 = 4 ASL=(1*6+2+3*3+4+9)/12=2.5