深圳南山 网站建设重庆网站排名推广
目录
一、队列
1.定义
2.应用
3.分类
(1)逻辑结构
(2)物理结构
顺序队列
链式队列
二、哈希存储
1.定义
2.哈希冲突
(1)开放定址法
(2)再哈希法
(3)链地址法
三、练习
1.链式队列
(1)创建队列
(2)入队(尾插)
(3)出队(头删)
(4)遍历打印
(5)清空队列
(6)销毁队列
(7)获取队头元素
2.哈希表
(1)创建哈希表
(2)设计哈希函数
(3)插入数据(头插)
(4)遍历打印
(5)查找(按姓名)
(6)清空哈希表
一、队列
1.定义
之前我们提到过的队列结构,也是一种线性存储的数据结构。
队列:从一端进行数据插入,另一端进行数据删除的线性存储结构。
队列均遵循FIFO,即先进的先出、后进的后出。
2.应用
缓冲区,缓存数据
3.分类
(1)逻辑结构
从逻辑结构上看,队列均为线性结构。
(2)物理结构
从物理结构上看,队列分为顺序队列与链式队列。
-
顺序队列
队头指向第一个元素,队尾指向最后一个元素后的空位置。
出队时队头向后移动,入队时队尾向后移动。
注:普通的顺序队列会出现“假溢出”的问题,即当队尾移动到队列外时,认为队列以满,数据溢出,但实际上队列空间并未用尽,造成内存浪费。
为解决“假溢出”问题,我们一般使用循环链表,即队列头尾相接。
1. 空队列:队头和队尾相遇
2. 满队列:(tail+1) 和队头在同一位置(牺牲了一个存储空间)
-
链式队列
链式队列即要求每个数据均有指针域,指向下一个元素。
循环队列与链式队列的比较:从时间上看,它们的时间复杂度均为O(1)。不过循环队列需事先申请好空间,使用期间不释放,而对于链队列,每次申请和释放结点也会存在一些时间开销,如果入队出队频繁,则两者还是有细微差异。
从空间上来看,循环队列必须有一个固定的长度,所以就有了存储元素个数和空间浪费的问题。而链队列不存在这个问题,尽管它需要一个指针域,会产生一些空间上的开销,但可以接受。所以在空间上,链式队列更加灵活。
总的来说,在可以确定队列长度最大值的情况下,建议用循环队列,如果你无法预估队列的长度时,则用链式队列。
二、哈希存储
1.定义
哈希存储,也称散列存储:将要存储数据的关键字和数据的存储位置之间建立对应的函数关系,即哈希函数。
哈希存储的目的是为了提高数据的查找效率。哈希存储的表现方式是哈希表。
哈希表:一段连续内存空间。
存储数据时,按照函数关系寻找存储位置;数据查找时,根据关键字进行函数映射得到数据的存储位置。
2.哈希冲突
哈希冲突,也称哈希矛盾,是指多个不同的输入值通过哈希函数处理后得到相同的输出值,这种情况在使用哈希表时经常发生。
为了解决这个问题,开发者们提出了多种方法,主要包括以下几种:
(1)开放定址法
开放定址法是一种在发生冲突时寻找另一个空闲地址的方法。这种方法的具体实现有多种,包括线性探测法、平方探测法等。
线性探测法是当发生冲突时,顺序查看表中下一个单元,直到找到空闲单元。平方探测法则是在冲突发生的位置前后进行跳跃式探测。
(2)再哈希法
再哈希法是构造多个不同的哈希函数,当发生冲突时,使用第二个、第三个等其他哈希函数计算新的地址,直到找到不冲突的地址为止。这种方法可以减少聚集现象,但会增加计算时间。
(3)链地址法
链地址法是将所有哈希地址相同的记录链接在同一链表中。当发生冲突时,冲突的元素将被添加到链表的末尾。这种方法适用于频繁插入和删除操作的场景。
三、练习
1.链式队列
(1)创建队列
(2)入队(尾插)
(3)出队(头删)
(4)遍历打印
(5)清空队列
(6)销毁队列
用valgrind工具验证销毁结果
(7)获取队头元素
2.哈希表
(1)创建哈希表
(2)设计哈希函数
(3)插入数据(头插)
(4)遍历打印
(5)查找(按姓名)
(6)清空哈希表
用valgrind工具查看清空结果