当前位置: 首页 > news >正文

数据结构实验-查找与排序算法

查找与排序算法

一、实验目的

1.掌握顺序查找、二分查找和冒泡排序的必要特点;
2.重点掌握顺序查找、二分查找和冒泡排序的过程 。
3.熟悉哈希查找的方法,能选择合适散列函数,实现不同冲突处理方法的散列表的查找、建立。
4.了解各种常用的查找算法和排序算法。

二、实验内容

基础性任务:
(1)给出在一个无序表中采用顺序查找算法查找值为x的元素的算法.
(2)给出在一个将无序表通过冒泡排序变为递增有序表的算法。
(3)给出在一个递增有序表中采用二分查找算法查找算法查找值为x的元素的算法。
即:编写程序实现顺序查找、冒泡排序和二分查找,其中,二分查找和冒泡排序的程序流程图如图1所示。
程序流程:main() 输入数据 seqsearch() bubblesort () binsearch ()

提高性任务(从下述任务中任选一个完成):
(1) 实现二叉排序树查找(整数);
随机产生一组关键字,利用二叉排序树的插入算法建立二叉排序树,然后删除某一指定关键字元素。
(2)实现哈希查找(一组整数),处理冲突的方法采用线性探测再散列法。
有一组关键字{19,01,23,14,55,20,84,27,68,11,10,77},采用哈希函数:H(key)=key % 13 ,采用开放地址法的线性探测方法解决冲突,试在 0~18 的散列地址空间中对该关键字序列构造哈希表。

三、实验要求

(1) 给出程序设计的基本思想、原理描述和算法实现。
(2) 对源程序给出注释。

四、实现提示

(1)查找表需要在运行时输入,查找关键字也是在运行时指定。
(2)顺序查找可采用顺序存储结构和链式存储结构,如果采用顺序存储结构,可以定义一个数组存放关键字。
(3)注意理解折半查找的适用条件(链表能否实现折半查找?冒泡排序呢?)。

五、实验步骤提示

基础性任务:
(1)理解相关查找算法和排序算法对存储结构及是否有序的要求及其算法思想;
(2)仔细分析实验内容,给出所用查找方法和冒泡排序方法的算法思想和算法流程图;
(3)用C或C++语言实现所用查找算法(已给出部分源代码,请将程序补充完整);
(4)给出测试数据,并分析其结果;在实验报告册上写出实验过程。
提高性任务(二选一):
(1)用C或C++语言实现二叉排序树查找算法;
(2)用C或C++语言实现采用线性探测再散列法的哈希查找算法。


在这里插入图片描述

六、源程序

6.1基础任务

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>#define DATA_SIZE 10// 函数声明
void seqsearch(int*, int);     // 顺序查找
void binsearch(int*, int);     // 二分查找
void bubblesort(int*, int);    // 冒泡排序
void menu();                   // 显示菜单
void printArray(int*, int);    // 打印数组int main() {int i, j = 1;int ch;int data[DATA_SIZE];printf("请输入10个整型数据: ");for (i = 0; i < DATA_SIZE; i++) {scanf("%d", &data[i]);}menu();  // 显示菜单while (j) {printf("\n请选择操作: ");scanf("%d", &ch);switch (ch) {case 1:seqsearch(data, DATA_SIZE);break;case 2:printf("执行二分查找前需要对数组排序...\n");bubblesort(data, DATA_SIZE);printf("排序后的数组: ");printArray(data, DATA_SIZE);binsearch(data, DATA_SIZE);break;case 3:bubblesort(data, DATA_SIZE);printf("排序后的数组: ");printArray(data, DATA_SIZE);break;case 4:j = 0;break;default:printf("无效的选择!\n");break;}if (j) {printf("\n当前数组状态: ");printArray(data, DATA_SIZE);menu();}}return 0;
}// 显示菜单
void menu() {printf("\n==== 菜单 ====\n");printf("1. 顺序查找\n");printf("2. 二分查找\n");printf("3. 冒泡排序\n");printf("4. 退出\n");
}// 打印数组
void printArray(int* arr, int n) {for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");
}// 顺序查找
void seqsearch(int* arr, int n) {int x, i;printf("请输入要查找的值: ");scanf("%d", &x);for (i = 0; i < n; i++) {if (arr[i] == x) {printf("找到元素 %d 在数组的第 %d 个位置(下标为%d)\n", x, i + 1, i);return;}}printf("未找到元素 %d\n", x);
}// 冒泡排序
void bubblesort(int* arr, int n) {int i, j, temp;for (i = 0; i < n - 1; i++) {for (j = 0; j < n - 1 - i; j++) {if (arr[j] > arr[j + 1]) {// 交换元素temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}// 二分查找
void binsearch(int* arr, int n) {int x, left = 0, right = n - 1, mid;printf("请输入要查找的值: ");scanf("%d", &x);while (left <= right) {mid = left + (right - left) / 2;if (arr[mid] == x) {printf("找到元素 %d 在数组的第 %d 个位置(下标为%d)\n", x, mid + 1, mid);return;}else if (arr[mid] < x) {left = mid + 1;}else {right = mid - 1;}}printf("未找到元素 %d\n", x);
}

6.2提高任务

(1)随机产生一组关键字,利用二叉排序树的插入算法建立二叉排序树,然后删除某一指定关键字元素。

(2)有一组关键字{19,01,23,14,55,20,84,27,68,11,10,77},采用哈希函数:H(key)=key % 13 ,采用开放地址法的线性探测方法解决冲突,试在 0~18 的散列地址空间中对该关键字序列构造哈希表。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#define HASH_SIZE 19  // 0-18的散列空间// 哈希表初始化
void initHashTable(int* hashTable) {for(int i = 0; i < HASH_SIZE; i++) {hashTable[i] = -1;  // -1表示空位置}
}// 哈希函数
int hashFunction(int key) {return key % 13;
}// 插入元素到哈希表
void insertHash(int* hashTable, int key) {int index = hashFunction(key);int originalIndex = index;while(hashTable[index] != -1) {  // 线性探测解决冲突index = (index + 1) % HASH_SIZE;if(index == originalIndex) {  // 表满printf("哈希表已满,无法插入 %d\n", key);return;}}hashTable[index] = key;printf("插入 %d 到位置 %d\n", key, index);
}// 在哈希表中查找元素
void searchHash(int* hashTable, int key) {int index = hashFunction(key);int originalIndex = index;while(hashTable[index] != key) {if(hashTable[index] == -1) {  // 遇到空位置,说明不存在printf("未找到 %d\n", key);return;}index = (index + 1) % HASH_SIZE;if(index == originalIndex) {  // 绕了一圈没找到printf("未找到 %d\n", key);return;}}printf("找到 %d 在位置 %d\n", key, index);
}// 打印哈希表
void printHashTable(int* hashTable) {printf("\n哈希表内容:\n");printf("位置\t值\n");for(int i = 0; i < HASH_SIZE; i++) {printf("%d\t%d\n", i, hashTable[i]);}
}// 哈希查找测试
void testHashSearch() {int hashTable[HASH_SIZE];initHashTable(hashTable);int keys[] = {19, 1, 23, 14, 55, 20, 84, 27, 68, 11, 10, 77};int n = sizeof(keys) / sizeof(keys[0]);// 插入关键字for(int i = 0; i < n; i++) {insertHash(hashTable, keys[i]);}printHashTable(hashTable);// 测试查找printf("\n测试查找:\n");searchHash(hashTable, 55);searchHash(hashTable, 20);searchHash(hashTable, 99);  // 不存在的值
}int main() {testHashSearch();return 0;
}

七、实验结果

算法思想

1.顺序查找(seqsearch):
从数组的第一个元素开始,逐个比较直到找到目标值或遍历完整个数组
时间复杂度:O(n)

2.冒泡排序(bubblesort):
通过多次遍历数组,每次比较相邻元素并交换顺序不正确的元素
每轮遍历后,最大的元素会"冒泡"到数组末尾
时间复杂度:O(n^2)

3.二分查找(binsearch):
适用于有序数组
每次与中间元素比较,缩小搜索范围
时间复杂度:O(log n)

4.菜单系统:
提供一个简单的命令行界面让用户选择操作
在执行二分查找前会自动进行排序

在这里插入图片描述
算法思想

1.二叉排序树实现:

使用递归方法实现了插入、查找和删除操作
删除操作考虑了三种情况:无子节点、有一个子节点和有两个子节点
提供了生成随机数创建二叉排序树的功能

2.哈希查找实现:
使用线性探测法解决冲突
实现了插入、查找、删除和显示功能
提供了示例测试函数,可以直接测试实验要求的关键字集合
使用两个特殊标记:EMPTY表示空位置,DELETED表示已删除位置

在这里插入图片描述
八、讨论和心得

通过这次实验,在之前学习C语言的基础上,我对几种排序查找算法有了进一步的认识。

1.查找算法:
顺序查找简单但效率低,适用于小数据量或无序数据
二分查找高效,但要求数据必须有序
哈希查找平均时间复杂度为O(1),但需要额外空间并处理冲突

2.排序算法:
冒泡排序实现简单,但效率低,适合教学演示
在实际应用中,如数据量大应考虑更高效的排序算法(如快速排序、归并排序等)

3.哈希表:
哈希查找性能优异,但需要设计好的哈希函数
线性探测法容易实现但可能导致聚集现象
装填因子(已用空间/总空间)影响哈希表性能

4.总结:
不同算法各有优缺点,应根据具体场景选择,理解算法思想比记住代码更重要,通过实现加深了对数据结构和算法的认识。

http://www.dtcms.com/a/296135.html

相关文章:

  • 游戏开发Unity/ ShaderLab学习路径
  • 【独立工具】小红书图片采集软件
  • ExoCode.ino - OpenExo
  • Lua(文件I/O)
  • Claude4、GPT4、Kimi K2、Gemini2.5、DeepSeek R1、Code Llama等2025主流AI编程大模型多维度对比分析报告
  • PHP 与 Vue.js 结合的前后端分离架构
  • 虚拟机导入导出ova文件
  • Nginx 运维实战:动静分离,加速静态资源访问!
  • vue3:十八、内容管理-搜索栏的完善
  • C++之Stack和Queue的常用函数+习题
  • 若依框架在 IDEA 中运行的前置软件环境配置指南
  • XORM完全指南:Go语言数据库操作从入门到进阶
  • DS18B20扩展:在数码管上显示温度时包含小数部分
  • 黑马点评系列问题之p44实战篇商户查询缓存 jmeter如何整
  • 【基础】go基础学习笔记
  • OpenCV —— 绘制图形
  • 实验研究 | VR虚拟现实环境中植物景观偏好与生理恢复性效益研究
  • linux端 RAGflow超详细小白教程(一)安装及环境搭建
  • Linux系统编程——网络
  • 河南萌新联赛2025第(二)场:河南农业大学(整除分块,二进制,树的搜索)
  • C++ explicit 上下文相关转换
  • 牛客多校04L :Ladder Challenge
  • 基于MASAC算法的建筑群需求响应系统设计与实现
  • 个人电脑 LLMOps 落地方案
  • pytest官方Tutorial所有示例详解(二)
  • 【AI】Java生态对接大语言模型:主流框架深度解析
  • FastAPI中间件
  • 如何在 conda 中删除环境
  • 常见半导体的介电常数
  • 告别下载中断:深入解析Tomcat JSP中的“远程主机强迫关闭连接”与“软件中止连接”