《妙趣横生的算法》(C语言实现)-第2章 常用的查找与排序方法

【实例2-1】一个结构体数组中存放的是学生记录,每条记录包括:学号、姓名、成绩。编写一个程序,要求输出1001编号同学的具体信息。

// 2-1 2023年12月23日18点05分-18点14分 
typedef struct student{ // 定义学生结构体类型 int id; // 学生编号char name[10]; // 学生姓名float score; // 学生成绩 
}Student;
int search(Student stu[], int n, int key)
{for (int i = 0; i < n; ++i) {if (stu[i].id == key) // 查找成功 return i;}return -1; // 查找失败 
}
# include <stdio.h>
int main()
{Student stu[4] = {{1004, "TOM", 100}, {1002, "LILY", 95}, {1001, "ANN", 93}, {1003, "LUCY", 98}}; // 初始化结构体数组// 顺序查找1001编号同学的具体信息int addr; // 要查找的记录的地址addr = search(stu, 4, 1001); printf("Student ID:   %d\n", stu[addr].id); // 输出查找到的记录的信息printf("Student name: %s\n", stu[addr].name); printf("Student score: %f\n", stu[addr].score);return 0;
} 

总结:顺序查找的优点在于简单直观,对于被查找的记录在文件中的排列顺序没有限制,因此比较适合顺序文件的查找。同时这种查找思想也适合于对顺序表数据结构和链表数据结构中的元素进行查找。它的缺点在于平均查找长度过大,查找效率低。逐个依次查找。
【实例2-2】折半查找数组中的元素。

// 2-2 2023年12月23日18点28分-
# include <stdio.h>
int bin_search(int A[], int n, int key)
{int low = 0, high = n - 1, mid;while (low <= high) {mid = (low + high) / 2; // 设置mid的值 if (A[mid] == key) {return mid; // 查找成功,返回mid}if (A[mid] < key) { low = mid + 1; // 在后半序列中查找 }if (A[mid] > key) {high = mid - 1; // 在前半序列中查找 }}return -1; // 查找失败,返回-1 
}
int main()
{int A[10] = {2, 3, 5, 7, 8, 10, 12, 15, 19, 21};printf("The contents of the array A[10] are\n");for (int i = 0; i < 10; ++i)printf("%d ", A[i]); // 显示数组A中的内容int n;printf("\nPlease input a integer for search\n");scanf("%d", & n); // 输入待查找的元素int addr = bin_search(A, 10, n); // 折半查找,返回该元素在数组中的下标if (-1 != addr)printf("%d is at the %dth unit in array A\n", n, addr + 1); // 查找成功 elseprintf("There is no %d in array A\n", n); // 查找失败 return 0;
}

总结:折半查找要考虑清楚上下界,是左闭右闭区间还是左闭右开区间。这和循环的终止条件有关。
【实例2-3】编写一个C程序,实现直接插入排序,要求从大到小排序,并输出排序后的数列元素。

// 2-3 2023年12月23日18点59分-19点09分 
void insertsort(int A[], int n)
{for (int i = 1; i < n; ++i) {int tmp = A[i]; // 将A[i]保存在临时变量tmp中int j = i - 1;while (j >= 0 && tmp > A[j]) { // 找到tmp的插入位置 A[j + 1] = A[j--]; // 将A[j]后移,再将j减1 }A[j + 1] = tmp; // 将元素tmp插入到指定位置,第i趟排序完成 }
}
# include <stdio.h> 
int main()
{int a[] = {-111, 2, 5, 6, 3, 7, 8, 0, 9, 12, 1}; // 初始化序列 printf("The original data array is\n");for (int i = 0; i < sizeof(a) / sizeof(int); ++i)printf("%d ", a[i]); // 显示原序列之中的元素 insertsort(a, sizeof(a) / sizeof(int)); // 插入排序 printf("\nThe result of insertion sorting for the array is\n");for (int i = 0; i < sizeof(a) / sizeof(int); ++i)printf("%d ", a[i]);return 0;
}

总结:插入排序,一个包含n个元素的序列,需要(n-1)趟排序,就可以使得这个序列有序。因为如果只包含一个元素肯定有序,如果包含两个及以上元素,那么就需要比较(n-1)次。
【实例2-4】编程实现选择排序,要求从大到小排序,并输出序列。

// 2-4 2023年12月23日19点22分-19点34分 
void selectionsort(int A[], int n) // 选择排序 
{for (int i = 0; i < n - 1; ++i) {int max = i;for (int j = i + 1; j < n; ++j) { // 在后(n-i)个元素中找到最大的元素位置 if (A[j] > A[max]) {max = j; // 用max记录下最大元素的位置 }}if (max != i) { // 如果最大的元素不位于后(n-i)个元素第1个 int tmp = A[max]; // 元素的交换 A[max] = A[i];A[i] = tmp;}}
} 
# include <stdio.h>
int main()
{int a[] = {-111, 2, 5, 6, 3, 7, 8, 0, 9, 12, 1}; // 初始化序列 printf("The original data array is\n");for (int i = 0; i < sizeof(a) / sizeof(int); ++i) {printf("%d ", a[i]); // 显示原序列的元素 }selectionsort(a, sizeof(a) / sizeof(int)); // 执行选择排序 printf("\nThe result of selection sort for the array is\n");for (int i = 0; i < sizeof(a) / sizeof(int); ++i) {printf("%d ", a[i]); // 输出排序后的结果 }return 0;
}

总结:选择排序,一个包含n个元素的序列需要(n-1)趟排序。每次找最小或者最大的元素放在前面位置。
【实例2-5】编写程序实现冒泡排序,要求从大到小排序并输出元素。

// 2-5 2023年12月23日19点42分-19点47分 
//void bubblesort(int A[], int n) // 冒泡排序 
//{
//    for (int i = n - 1; i > 0; --i) {
//        for (int j = 0; j < i; ++j) {
//            if (A[j] < A[j + 1]) {
//                int tmp = A[j];
//                A[j] = A[j + 1];
//                A[j + 1] = tmp;
//            }
//        }
//    }
//} 
void bubblesort(int A[], int n) // 改进的冒泡排序 
{int flg = 1;for (int i = n - 1; i > 0 && flg == 1; --i) {flg = 0;for (int j = 0; j < i; ++j) {if (A[j] < A[j + 1]) {int tmp = A[j];A[j] = A[j + 1];A[j + 1] = tmp;flg = 1; // 发生数据交换flg置1 }}}
} 
# include <stdio.h>
int main()
{int a[] = {-111, 2, 5, 6, 3, 7, 8, 0, 9, 12, 1}; // 初始化序列 printf("The original data array is\n");for (int i = 0; i < sizeof(a) / sizeof(int); ++i)printf("%d ", a[i]); // 显示原序列 bubblesort(a, sizeof(a) / sizeof(int)); // 执行冒泡排序 printf("\nThe result of bubble sort of this array is\n");for (int i = 0; i < sizeof(a) / sizeof(int); ++i)printf("%d ", a[i]); // 输出排序后的结果 return 0;
}

总结:冒泡排序,一个包含n个元素的序列需要(n-1)趟排序。每次确定了一个最大元素,冒泡冒出来的。改进后的冒泡排序算法可以减少排序时的比较次数,提高冒泡排序的效率。
【实例2-6】编写程序实现希尔排序。

// 2-6 2023年12月23日20点01分-20点10分
void shellsort(int A[], int n) // 希尔排序 
{int gap = n;int flg, j;while (gap > 1) {gap /= 2; // 增量缩小,每次减半do { // 子序列应用冒泡排序 flg = 0;for (int i = 1; i <= n - gap; ++i) {j = i + gap;if (A[i] < A[j]) {int tmp = A[i];A[i] = A[j];A[j] = tmp;flg = 1;}} } while (flg != 0); } 
} 
# include <stdio.h>
int main()
{int a[] = {-111, 2, 5, 6, 3, 7, 8, 0, 9, 12, 1}; // 初始化序列 printf("The original data array is\n");for (int i = 0; i < 10; ++i)printf("%d ", a[i+1]); // 显示原序列 shellsort(a, 10); // 执行希尔排序 printf("\nThe result of bubble sort of this array is\n");for (int i = 0; i < 10; ++i)printf("%d ", a[i+1]); // 输出排序后的结果 return 0;
}

【实例2-7】快速排序。

// 2-7 2023年12月23日20点13分-20点21分 
void swap(int * a, int * b) // 序列中元素位置的交换 
{int tmp = * a;* a = * b;* b = tmp;
}
void quicksort(int A[], int s, int t)
{if (s < t) {int i = s, j = t + 1;while (1) {do {++i;} while (!(A[s] >= A[i] || i == t)); // 重复执行++i操作do {--j;} while (!(A[s] <= A[j] || j == s)); // 重复执行--j操作if (i < j)swap(& A[i], & A[j]); // 交换位置elsebreak; }swap(& A[s], & A[j]); // 交换基准元素与A[j]的位置 quicksort(A, s, j - 1); // 递归排序基准元素前面的子序列 quicksort(A, j + 1, t); // 递归排序基准元素后面的子序列 }
}
# include <stdio.h>
int main()
{int a[] = {2, 5, 6, 3, 7, 8, 0, 9, 12, 1}; // 初始化序列 printf("The original data array is\n");for (int i = 0; i < sizeof(a) / sizeof(int); ++i) {printf("%d ", a[i]); // 显示原序列的元素 }quicksort(a, 0, sizeof(a) / sizeof(int) - 1); // 执行快速排序 printf("\nThe result of selection sort for the array is\n");for (int i = 0; i < sizeof(a) / sizeof(int); ++i) {printf("%d ", a[i]); // 输出排序后的结果 }return 0;
}

总结:这个程序有问题,尚在寻找中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/241921.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络7层架构

网络 7 层架构 什么是OSI七层模型&#xff1f; OSI模型用于定义并理解数据从一台计算机转移到另一台计算机&#xff0c;在最基本的形式中&#xff0c;两台计算机通过网线和连接器相互连接&#xff0c;在网卡的帮助下共享数据&#xff0c;形成一个网络&#xff0c;但是一台计算…

正餐---二叉树的OJ题

目录​​​​​​​ 前言&#x1f36f; 1. 检查两颗树是否相同&#x1f947; 1.1 思路分析&#x1fa99; 1.2 代码实现&#x1f9f0; 2. 单值二叉树&#x1f332; 2.1 思路分析&#x1f52e; 2.2 代码实现&#x1f488; 3. 二叉树的前序遍历&#x1f39f;️ 3.1 思路分…

【数据结构】线性表

一.线性表 1.定义&#xff1a; n个同类型数据元素的有限序列&#xff0c;记为 L为表名&#xff0c;i为数据元素在线性表中的位序&#xff0c;n为线性表的表长&#xff0c;n0时称为空表。 2.数据元素之间的关系&#xff1a; 直接前驱和直接后继 3.抽象数据类型线性表的定义…

SQL进阶:多表查询

在SQL基础部分,我们在讲解的过程中只用到了单表查询。但实际上,常见的业务场景单表查询不能满足,或者拆分查询性能过慢。这个时候我们就需要用到连接查询。即查询多表按一定规则合并后的数据。 注意,合并后的数据也是表,也有列的概念,只不过一般存储在内存中。 由于集合…

jQuery 实现带手柄自由调整页面大小的功能

在https://blog.csdn.net/qq_44327851/article/details/135006421文章中提到了用纯JavaScript实现自由调整页面大小的功能&#xff0c;其中有基础版和优化版&#xff0c;优化版通过添加手柄解决了基础版在调整页面大小的时候不够灵活的问题&#xff0c;其实解决不够灵活的问题还…

git首次使用--去公司第一次拉取

文章目录 一&#xff0c; 在企业中首次拉取项目二&#xff0c;提交项目1. 提交----新添加的文件2. 将分支上的代码同步到master3. 提交----更改后的文件 三&#xff0c;常见问题1. Git Pull Failed 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一&am…

固定效应模型-以stata为工具

固定效应模型-以stata为工具 文章目录 1.固定效应模型2. 模型原理3. `stata`代码实现1.固定效应模型 固定效应模型(Fixed Effects Model)是一种面板数据分析方法,通过引入个体固定效应来控制个体间的异质性,并更准确地估计解释变量对因变量的影响。它在许多经济、社会科学…

(五)Python 垃圾回收机制

一、垃圾回收的工作原理 Python的垃圾回收机制是自动的&#xff0c;负责管理程序中的内存。它基于两种主要技术&#xff1a;引用计数和循环引用检测器。 引用计数 每当一个对象被引用时&#xff0c;Python会增加该对象的引用计数&#xff1b;每当一个对象不再被引用时&#…

qt项目-《图像标注软件》源码阅读笔记-类图

目录 1. 开源项目链接 2. 项目界面 3. 项目类图 3.1 形状的绘制及形状的存储 3.2 主窗口中心组件的界面管理 3.3 Command负责实现撤销和重做功能 3.4 其他类 3.5 枚举 3.5.1 Status 主窗口的状态变量 3.5.2 Mode 主窗口模式状态变量 3.5.3 shapeStatus 中心组件状态…

josef约瑟 电流继电器 RL-D1 电压AC220V 整定范围0-9.99AAC

系列型号 RL-D1型电流继电器&#xff1b; RL-D2型电流继电器&#xff1b; 基本参数 RL-D系列电流继电器用于发电机、变压器和输电线的过负荷和短路保护装置中作为启动元件。本继电器为集成电路型继电器&#xff0c;精度高、功耗小、动作时间快&#xff0c; 返回系数高、整定…

AndroidStudio无法新建aidl文件解决办法

我用的 AS 版本是 Android Studio Giraffe | 2022.3.1 Build #AI-223.8836.35.2231.10406996, built on June 29, 2023 右键新建 aidl 文件&#xff0c; 提示 (AIDL File)Requires setting the buildFeatures.aidl to true in the build file 解决办法 修改 app 的 build.…

03_排序

03_排序 一、简单排序Comparable接口介绍需求&#xff1a; 冒泡排序排序原理&#xff1a;冒泡排序API设计&#xff1a; 选择排序排序原理&#xff1a;选择排序API设计&#xff1a;选择排序的时间复杂度分析&#xff1a; 插入排序需求&#xff1a;排序原理&#xff1a;插入排序A…

三菱人机交互GT Designer的安装

今天&#xff0c;与小编一起来学习三菱的GT Designer软件&#xff0c;下面就是小编记录的软件查找&#xff0c;安装的全过程&#xff0c;希望对你学习三菱有帮助。 目录 安装 选择官网下载安装包 解压安装包进行安装 创建一个工程 安装 选择官网下载安装包 三菱&#xff08;中…

如何在linux安装软件

一.安装种类 1.编译安装&#xff1a;灵活性高&#xff0c;难度较大&#xff0c; 可以安装新版本 2.rpm安装&#xff1a;查软件信息&#xff0c;是否安装&#xff0c;文件列表 3.yum&#xff1a;是rpm的升级版本&#xff0c;解决rpm的弊端 rpm安装&#xff1a; 安装软件的时…

【架构】ServerLess

文章目录 概述什么是serverless无服务与传统模式架构区别serverless优缺点使用serverless的应用场景有哪些“无服务器”搭建网站Serverless的落地案例来源 概述 架构 单体&#xff08;三层架构&#xff09;微服务分布式ServerLess 什么是serverless无服务 serverless中文的…

36.MYSQL的外键(foreign key)

外键&#xff08;Foreign Key&#xff09;是关系数据库中的一种约束&#xff0c;用于建立表与表之间的关联关系。外键定义了两个表之间的从属关系&#xff0c;它指向另一个表中的主键&#xff0c;用于维护数据的完整性和一致性。 外键分为两个角色&#xff1a;主表和从表。主表…

VirtualBox虚拟机使用USB3.0网卡与开发板通信

因为我的笔记本没有带网口&#xff0c;所以我使用的是USB网卡。我按照网上其他人发的“VirtualBox与开发板、主机相互ping通”文章中提到的方法&#xff0c;进行网络设置后发现仍然无法实现Ubuntu虚拟机与主机和Linux开发板相互ping通。 仔细回想以前Ubuntu虚拟机使用USB读卡器…

用户表格及筛选表单配置 - PC通用管理模块(1)

用户表格及筛选表单配置 - PC通用管理模块(1) 多八多AiIDE - 用户管理页面配置教程 第一课&#xff1a;基础查询配置 目标 配置基础的PC端通用管理模块。添加前端自定义组件以显示管理页面。配置列表表格字段。配置筛选表单。 步骤 1. 注册和新建应用 访问多八多AiIDE平台…

Docker - 镜像 | 容器 日常开发常用指令 + 演示(一文通关)

目录 Docker 开发常用指令汇总 辅助命令 docker version docker info docker --help 镜像命令 查看镜像信息 下载镜像 搜索镜像 删除镜像 容器命令 查看运行中的容器 运行容器 停止、启动、重启、暂停、恢复容器 杀死容器 删除容器 查看容器日志 进入容器内部…

SpringSecurity【3】之授权

继续昨天的认证&#xff0c;今天来分析 在Spring Security中&#xff0c;授权是指对用户访问系统资源的限制。Spring Security提供了多种授权方式&#xff0c;包括基于角色的授权、基于表达式的授权、注解授权等。 基于角色的授权是指通过为用户分配不同的角色来限制其访问系统…