查找——顺序查找和折半查找

2024-06-16 13:36
文章标签 查找 顺序 折半

本文主要是介绍查找——顺序查找和折半查找,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

查找

关于顺序查找和折半查找,可点击此处进入旧金山大学提供的动画演示网站。

顺序查找

​ 顺序查找又称线性查找。它对于顺序表和链表都是适用的。对于顺序表,可通过数组下标递增来顺序扫描每个元素;对于链表,则通过指针next来依次扫描每个元素。

​ 本次顺序表用指针,也就是申请一个堆空间,使用方式和数组还是一致。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>typedef int ElemType;
typedef struct {// 整型指针ElemType *elem;// 存储动态数组里面元素的个数int table_len;
} SSTable;/** 顺序表初始化*/
void st_init(SSTable &ST, int len) {// 多申请一个位置用来存哨兵ST.table_len = len + 1;ST.elem = (ElemType *) malloc(sizeof(ElemType) * ST.table_len);// 筛子srand(time(NULL));// 随机数生成数据for (int i = 1; i < ST.table_len; i++) {// 生产的数字都在0-99中间ST.elem[i] = rand() % 100;}
}/** 打印顺序表*/
void st_print(SSTable ST) {for (int i = 1; i< ST.table_len; i++) {printf("%3d", ST.elem[i]);}printf("\n");
}/** 查找元素位置*/
int search_seq(SSTable ST, ElemType key) {// 零号元素作为哨兵// 遍历数组时 可以少写一个 i >= 0 的判断ST.elem[0] = key;int i;// 从后往前找// 如果找到 i刚好是对应的位置for (i = ST.table_len - 1; ST.elem[i] != key; i--);return i;
}int main() {SSTable ST;// 一、顺序表初始化st_init(ST, 10);// 二、打印顺序表st_print(ST);// 存储元素ElemType key;printf("please input search key:\n");scanf("%d", &key);// 元素存储位置int pos;pos = search_seq(ST, key);if (pos) {printf("search elem success, location: %d\n", pos);} else {printf("search elem failed\n");}return 0;
}

折半查找

​ 折半查找又称为二分查找,它仅适用于有序的顺序表。

折半查找的基本思想:首先将给定值key与表中间位置的元素比较。若相等,则查找成功,返回该元素的存储位置。若不等,则所需要查找的元素只能在中间元素以外的前半部分或后半部分(例如:在查找表升序排列时,若给定值key大于中间元素,则查找的元素只可能在后半部分),然后再缩小的范围内继续进行同样的查找,如此重复,直到找到为止。或确定表中没有所需要查找的元素,则查找不成功,返回查找失败的信息。

​ 针对顺序表有序,使用 qsort 来排序, qsort 的使用方法如下:

#include <stdlib.h>void qsort(void *buf, size_t num, size_t size, int (*compare)(const void*, const void*));
  • buf:要排序数组的起始地址,也可以是指针,申请了一块连续的堆空间。
  • num:数组中元素的个数。
  • size:数组中每个元素所占用的空间大小。
  • compare:比较规则,需要我们传递一个函数名,这个函数由我们自己编写,返回值必须是 int 类型,形参是两个 void 类型指针,这个函数我们编写,但是由qsort内部调用,相当于我们传递一种行为给qsort。

折半查找不需要用到哨兵,因此不要受上一节顺序查找的影响,代码实战流程是:

  1. 我们初始化顺序表,随机10个元素。
  2. 使用 qsort 进行排序,排序完毕后,打印。
  3. 输入要查找的元素值,存入变量 key 中。
  4. 通过二分查找查找对应 key 值,找到则输入在顺序表中的位置,没找到输出未找到。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>typedef int ElemType;
typedef struct {// 整型指针ElemType *elem;// 存储动态数组里面元素的个数int table_len;
} SSTable;/** 顺序表初始化*/
void st_init(SSTable &ST, int len) {// 折半查找不使用0号位置作为哨兵ST.table_len = len;ST.elem = (ElemType *) malloc(sizeof(ElemType) * ST.table_len);// 筛子srand(time(NULL));// 随机数生成数据for (int i = 0; i < ST.table_len; i++) {// 生产的数字都在0-99中间ST.elem[i] = rand() % 100;}
}/** 打印顺序表*/
void st_print(SSTable ST) {for (int i = 0; i < ST.table_len; i++) {printf("%3d", ST.elem[i]);}printf("\n");
}/** 比较两个值的大小*/
int compare(const void *left, const void *right) {// 从大到小排序// return *(ElemType *)right - *(ElemType *)left;// 从小到大排序return *(ElemType *)left - *(ElemType *)right;
}/** 二分查找*/
int binary_search(SSTable L, ElemType key) {int low = 0, high = L.table_len, mid;while (low <= high) {mid = (low + high) / 2;if (L.elem[mid] == key) {// 找到了return mid;} else if (L.elem[mid] > key) {high = mid - 1;} else if (L.elem[mid] < key) {low = mid + 1;}}// 没有找到 不返回0是因为元素可能会在0号位置return -1;
}int main() {SSTable ST;// 一、顺序表初始化st_init(ST, 10);// 二、打印顺序表st_print(ST);// 三、排序qsort(ST.elem, ST.table_len, sizeof(ElemType), compare);st_print(ST);// 存储元素ElemType key;printf("please input search key:\n");scanf("%d", &key);// 元素存储位置int pos;pos = binary_search(ST, key);if (-1 != pos) {printf("find success, pos = %d\n", pos);} else {printf("find failed\n");}return 0;
}

这篇关于查找——顺序查找和折半查找的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1066596

相关文章

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

MySQL中查找重复值的实现

《MySQL中查找重复值的实现》查找重复值是一项常见需求,比如在数据清理、数据分析、数据质量检查等场景下,我们常常需要找出表中某列或多列的重复值,具有一定的参考价值,感兴趣的可以了解一下... 目录技术背景实现步骤方法一:使用GROUP BY和HAVING子句方法二:仅返回重复值方法三:返回完整记录方法四:

Spring如何使用注解@DependsOn控制Bean加载顺序

《Spring如何使用注解@DependsOn控制Bean加载顺序》:本文主要介绍Spring如何使用注解@DependsOn控制Bean加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录1.javascript 前言2. 代码实现总结1. 前言默认情况下,Spring加载Bean的顺

C++作用域和标识符查找规则详解

《C++作用域和标识符查找规则详解》在C++中,作用域(Scope)和标识符查找(IdentifierLookup)是理解代码行为的重要概念,本文将详细介绍这些规则,并通过实例来说明它们的工作原理,需... 目录作用域标识符查找规则1. 普通查找(Ordinary Lookup)2. 限定查找(Qualif

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co

MySQL中SQL的执行顺序详解

《MySQL中SQL的执行顺序详解》:本文主要介绍MySQL中SQL的执行顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql中SQL的执行顺序SQL执行顺序MySQL的执行顺序SELECT语句定义SELECT语句执行顺序总结MySQL中SQL的执行顺序

C#实现查找并删除PDF中的空白页面

《C#实现查找并删除PDF中的空白页面》PDF文件中的空白页并不少见,因为它们有可能是作者有意留下的,也有可能是在处理文档时不小心添加的,下面我们来看看如何使用Spire.PDFfor.NET通过C#... 目录安装 Spire.PDF for .NETC# 查找并删除 PDF 文档中的空白页C# 添加与删

SpringBoot中配置文件的加载顺序解读

《SpringBoot中配置文件的加载顺序解读》:本文主要介绍SpringBoot中配置文件的加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot配置文件的加载顺序1、命令⾏参数2、Java系统属性3、操作系统环境变量5、项目【外部】的ap

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想