《大话数据结构》笔记——第8章 查找(一)

声明:

本博客是本人在学习《大话数据结构》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。

本博客已标明出处,如有侵权请告知,马上删除。

8.1 开场白

8.2 查找概述

只要你打开电脑,就会涉及到查找技术。如炒股软件中查股票信息、硬盘文件中找照片、在光盘中搜 DVD ,甚至玩游戏时在内存中查找攻击力、魅力值等数据修改用来作弊等,都要涉及到查找。当然,在互联网上査找信息就更加是家常便饭。所有这些需要被查的数据所在的集合,我们给它一个统称叫查找表。

査找表(Search Table) 是由同一类型的数据元素(或记录)构成的集合。例如图 8-2-1 就是一个查找表。

关键字( Key )是数据元素中某个数据项的值,又称为键值,用它可以标识一个数据元素。也可以标识一个记录的某个数据项(字段),我们称为关键码,如下图中(1)和(2)所示。

若此关键字可以唯一地标识一个记录,则称此关键字为主关键字( Primary Key )。 注意这也就意味着,对不同的记录,其主关键字均不相同。主关键字所在的数据项称为主关键码,如下图中(3)和(4)所示。

那么对于那些可以识别多个数据元素(或记录)的关键字,我们称为次关键字( SecondaryKey ),如下图中(5)所示。次关键字也可以理解为是不以唯一标识一个数据元素(或记录)的关键字,它对应的数据项就是次关键码

在这里插入图片描述

查找( Searching )就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)

若表中存在这样的一个记录,则称查找是成功的,此时查找的结果给出整个记录的信息,或指示该记录在查找表中的位置。比如上图所示,如果我们查找主关键码 “代码” 的主关键字为 “sh601398” 的记录时,就可以得到第 2 条唯一记录。如果我们查找次关键码 “涨跌额” 为 “-0.11” 的记录时,就可以得到两条记录。

若表中不存在关键字等于给定值的记录,则称查找不成功,此时查找的结果可给出一个 “空” 记录或 “空” 指针。

查找表按照操作方式来分有两大种:静态查找表动态查找表

静态査找表( Static Search Table ):只作査找操作的查找表。它的主要操作有:

  1. 查询某个 “特定的” 数据元素是否在查找表中。
  2. 检索某个 “特定的” 数据元素和各种属性。

按照我们大多数人的理解,查找,当然是在已经有的数据中找到我们需要的。静态查找就是在干这样的事情,不过,现实中还有存在这样的应用:查找的目的不仅仅只是查找。

比如网络时代的新名词,如反应年轻人生活的 “蜗居” 、 “蚁族” 、 “孩奴” 、 “啃老” 等,以及 “X 客” 系列如博客、播客、闪客、黑客、威客等,如果需要将它们收录到汉语词典中,显然收录时就需要查找它们是否存在,以及找到如果不存在时应该收录的位置。再比如,如果你需要对某网站上亿的注册用户进行清理工作,注销一些非法用户,你就需查找到它们后进行删除,删除后其实整个查找表也会发生变化。对于这样的应用,我们就引入了动态査找表。

动态査找表(Dynamic Search Table ):在査找过程中同时插入査找表中不存在的数据元素,或者从査找表中删除已经存在的某个数据元素。显然动态查找表的操作就是两个:

  1. 查找时插入数据元素。

  2. 查找时删除数据元素。

为了提高查找的效率,我们需要专门为查找操作设置数据结构,这种面向查找操作的数据结构称为查找结构

从逻辑上来说,查找所基于的数据结构是集合,集合中的记录之间没有本质关系。可是要想获得较高的查找性能,我们就不能不改变数据元素之间的关系,在存储时可以将査找集合组织成表、树等结构。

例如,对于静态查找表来说,我们不妨应用线性表结构来组织数据,这样可以使用顺序査找算法,如果再对主关键字排序,则可以应用折半查找等技术进行高效的查找。

如果是需要动态查找,则会复杂一些,可以考虑二叉排序树的查找技术

另外,还可以用散列表结构来解决一些查找问题,这些技术都将在后面的讲解中说明 。

8.3 顺序查找

试想一下,要在散落的一大堆书中找到你需要的那本有多么麻烦。碰到这种情况的人大都会考虑做一件事,那就是把这些书排列整齐,比如竖起来放置在书架上,这样根据书名,就很容易查找到需要的图书,如图 8-3-1 所示。

在这里插入图片描述

散落的图书可以理解为一个集合,而将它们排列整齐,就如同是将此集合构造成一个线性表。我们要针对这一线性表进行査找操作,因此它就是静态查找表

此时图书尽管已经排列整齐,但还没有分类,因此我们要找书只能从头到尾或从尾到头一本一本查看,直到找到或全部查找完为止。这就是我们现在要讲的顺序查找。

顺序査找( Sequential Search )又叫线性査找,是最基本的査找技术,它的査找过程是:从表中第一个(或最后一个)记录开始,逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所査的记录;如果直到最后一个(或第一个)记录,其关键字和给定值比较都不等时,则表中没有所查的记录,查找不成功

8.3.1 顺序表查找算法

顺序查找的算法实现如下:

/* 顺序查找,a 为数组,n 为要查找的数组个数,key 为要查找的关键字*/ 
int Sequential_Search(int *a, int n, int key)
{
   
	int i;
	for (i = 1; i <= n; i++)
	{
   
		if (a[i] == key)
		{
   
			return i;
		}
	}
	return 0;
}

这段代码非常简单,就是在数组 a ( 注意元素值从下标 1 开始 )中查看有没有关键字( key ),当你需要查找复杂表结构的记录时,只需要把数组 a 与关键字 key 定义成你需要的表结构和数据类型即可。

8.3.2 顺序表查找优化

到这里并非足够完美,因为每次循环时都需要对 i 是否越界,即是否小于等于 n 作判断。事实上,还可以有更好一点的办法,设置一个哨兵,可以解决不需要每次让 i 与 n 作比较。看下面的改进后的顺序查找算法代码。

/* 有哨兵顺序查找 */
int Sequential_Search2(int *a, int n, int key)
{
   
	int i;
	a[0] = key; /* 设置 a[0] 为关键字值,我们称之为“哨兵” */
	i = n;	/* 循环从数组尾部开始 */
	while (a
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bm1998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值