C语言第九周课——经典算法

目录

一、冒泡法排序

1.1原理

1.2代码实现(以升序排序为例) 

1.3逻辑 

1.4分析

二、二分法查找

2.1原理

2.2代码实现 

2.3逻辑

2.4算法效率分析

三、素数判断

3.1原理

3.2代码实现

3.3逻辑

3.4分析


一、冒泡法排序

1.1原理

  • 冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
  • 这个算法的名字由来是因为越小的元素会经由交换慢慢 “浮” 到数列的顶端(升序排序的情况下),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样。

1.2代码实现(以升序排序为例) 

#include<stdio.h>
// 定义数组长度
#define SIZE 3
int main()
{
    int arr[SIZE];
    int i;

    // 从控制台输入数字到数组
    printf("请输入%d个整数:\n", SIZE);
    for (i = 0; i < SIZE; i++)
    {
        scanf("%d", &arr[i]);
    }

	int n = SIZE;
	int h, j, temp;
    for (h = 0; h < n - 1; h++)
    {
        for (j = 0; j < n - h - 1; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                // 交换元素
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }

    // 输出排序后的数组
    printf("排序后的数组为:\n");
    for (i = 0; i < SIZE; i++)
    {
        printf("%d ", arr[i]);
    }
	printf("\n");
    return 0;
}

1.3逻辑 

在这段代码中:

 
  • main函数里,首先通过循环和scanf函数从控制台接收用户输入的数字,并存储到数组arr中。
  • 然后通过两层循环来对输入的数组进行冒泡排序。
  • 最后再通过循环将排序后的数组元素输出到控制台。

1.4分析

  1. 时间复杂度分析
    • 最好情况:当输入的数组已经是有序的情况下,冒泡排序只需要进行一轮比较,没有元素交换操作。此时时间复杂度为,其中n是数组的长度。
    • 最坏情况:当输入的数组是逆序的情况下,需要进行n-1轮比较,每一轮比较的次数逐渐减少,总的比较次数是,时间复杂度为。
    • 平均情况:时间复杂度也是,因为在平均情况下,数组元素的无序程度介于最好情况和最坏情况之间。
  2. 空间复杂度分析
    • 冒泡排序是一种就地排序算法,它只需要一个额外的临时变量temp来交换元素的位置,所以空间复杂度为。这意味着它在排序过程中不需要额外的大量存储空间,只需要对原始数组进行操作即可。

二、二分法查找

2.1原理

二分查找(Binary Search),也叫折半查找,是一种在有序数组中查找特定元素的高效算法。它的基本思想是:

 
  • 每次比较中间元素与目标元素的值。
  • 如果中间元素的值等于目标元素的值,那么就找到了目标元素,查找结束。
  • 如果中间元素的值大于目标元素的值(因为是降序数组),则目标元素可能在数组的左半部分,所以下一次查找在左半部分继续进行。
  • 如果中间元素的值小于目标元素的值,则目标元素可能在数组的右半部分,下一次查找就在右半部分继续进行。
 

通过不断地将查找范围缩小一半,直到找到目标元素或者确定目标元素不存在为止。

2.2代码实现 

#include <stdio.h>
// 定义数组长度
#define SIZE 10
int main()
{
    int arr[SIZE] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    int target;

    // 从控制台输入要查找的目标数字
    printf("请输入要查找的数字:\n");
    scanf("%d", &target);

    int left = 0;
    int right = SIZE - 1;
    int result = -1; // 先假设未找到,赋值为 -1

    while (left <= right)
    {
        // 计算中间元素的索引
        int mid = left + (right - left) / 2;

        if (arr[mid] == target)
        {
            result = mid;
            break; // 找到目标元素,退出循环
        }
        else if (arr[mid] < target)
        {
            right = mid - 1;
        }
        else
        {
            left = mid + 1;
        }
    }

    if (result!= -1)
    {
        printf("目标数字 %d 在数组中的索引为 %d\n", target, result);
    }
    else
    {
        printf("未找到目标数字 %d\n", target);
    }

    return 0;
}

2.3逻辑

① 头文件包含

这行代码引入了标准输入输出头文件stdio.h,使得程序能够使用printfscanf等函数来进行控制台的输入输出操作。

②数组定义与初始化

  • 首先通过#define指令定义了一个常量SIZE来表示数组的长度,这里设置为10

  • main函数内部,定义并初始化了一个名为arr的整数数组,数组元素按照降序排列,从101。这个数组是后续进行二分查找的对象。

③目标数字输入

  • 定义了一个整型变量target,用于存储用户从控制台输入的要查找的目标数字。

  • 通过printf函数输出提示信息,引导用户输入数字,然后使用scanf函数从控制台读取用户输入的整数,并将其存储到target变量中。

④二分查找逻辑

  • 首先初始化了三个整型变量:

    • left:用于表示查找范围的左边界,初始化为0,即数组的起始索引。

    • right:表示查找范围的右边界,初始化为SIZE - 1,也就是数组的最后一个元素的索引。

    • result:用于存储最终查找结果的索引,初始化为-1,表示先假设目标数字未找到。

  • 然后进入一个while循环,只要left小于等于right,就说明查找范围还有效,继续进行查找操作:

    • 在每次循环中,先通过公式mid = left + (right - left) / 2计算出当前查找范围的中间元素的索引mid。这个公式的目的是为了避免整数溢出问题(相比于直接使用(left + right) / 2)。

    • 接着通过if - else if - else语句来比较中间元素arr[mid]与目标元素target的大小关系:

      • 如果arr[mid]等于target,说明找到了目标元素,将mid赋值给result,并通过break语句退出循环。

      • 如果arr[mid]小于target,由于数组是降序排列的,所以目标元素应该在当前中间元素的左边,因此将right更新为mid - 1,缩小查找范围到左半部分。

      • 如果arr[mid]大于target,则目标元素应该在当前中间元素的右边,所以将left更新为mid + 1,缩小查找范围到右半部分。

⑤查找结果输出

  • 根据result变量的值来判断是否找到目标数字。如果result不等于-1,说明找到了目标数字,通过printf函数输出目标数字及其在数组中的索引;如果result等于-1,则表示未找到目标数字,同样通过printf函数输出相应的提示信息。不过这里代码最后输出提示信息时有个小错误,printf("未找到目标数字 %d\n", darget);应该是printf("未找到目标数字 %d\n", target);,即把错误的darget修正为target

2.4算法效率分析

二分查找算法的时间复杂度为O(log n),其中n是数组的长度。在每次循环中,查找范围都会缩小一半,所以经过对数级别的次数就能找到目标元素(如果存在的话)或者确定其不存在。相比于简单的顺序查找(时间复杂度为),二分查找在处理大型有序数组时效率更高。

 

总体而言,这段代码实现了一个基本的二分查找功能,但需要注意修正输出提示信息时的拼写错误以确保代码的正确性。

三、素数判断

3.1原理

素数是指一个大于 1 且除了 1 和它自身外,不能被其他自然数整除的数。

①素数的定义及判断依据

根据素数的定义,要判断一个数n是否为素数,需要检查它是否能被 2 到n - 1之间的任何数整除。如果在这个范围内都不能被整除,那么n就是素数;反之,如果能被其中某个数整除,那么n就不是素数。

②程序实现思路

本程序通过两层循环来实现对 1 到 100 之内素数的判断:

  • 外层循环负责遍历 1 到 100 之间的每一个整数,从 2 开始(因为 1 不是素数),依次对每个数进行素数判断操作。

  • 对于外层循环遍历到的每一个整数,内层循环用于具体检查该数是否能被 2 到它自身减 1 之间的数整除。通过内层循环的检查结果来确定该数是否为素数。

3.2代码实现

#include <stdio.h>
int main()
{
    int i, j;

    printf("1到100之内的素数有:\n");

    // 遍历1到100的数字
    for (i = 2; i <= 100; i++)
    {
        // 假设当前数字i是素数
        int isPrime = 1;

        // 检查i是否能被2到i-1之间的数字整除
        for (j = 2; j < i; j++)
        {
            if (i % j == 0)
            {
                // 如果能被整除,说明不是素数,标记为0
                isPrime = 0;
                break;
            }
        }

        // 如果isPrime为1,说明是素数,输出该数字
        if (isPrime == 1)
        {
            printf("%d ", i);
        }
    }

    printf("\n");

    return 0;
}

3.3逻辑

在这个程序中:

  • main函数中,首先定义了两个整型变量ij,分别用于外层循环和内层循环的计数。
  • 通过printf函数输出提示信息,表示接下来要输出 1 到 100 之内的素数。
  • 然后是外层循环for (i = 2; i <= 100; i++),它会从 2 开始,每次递增 1,直到 100 为止,依次遍历这个范围内的每一个整数。对于每一个遍历到的整数i,都要进行是否为素数的判断。
 
  • 外层循环for (i = 2; i <= 100; i++)用于遍历从 2 到 100 的每一个整数。因为 1 不是素数,所以从 2 开始遍历。
  • 对于每一个要判断的整数i,首先在内层循环之前假设它是素数,通过设置isPrime = 1来表示。
  • 内层循环for (j = 2; j < i; j++)用于检查当前整数i是否能被 2 到i - 1之间的任何一个整数整除。如果能被整除(即i % j == 0),那么就说明i不是素数,此时将isPrime标记为 0,并通过break语句跳出内层循环,因为一旦确定不是素数就不需要再继续检查了。
  • 最后,当内层循环结束后,如果isPrime的值仍然为 1,就说明i是素数,通过printf函数输出该数字。

3.4分析

这种判断素数的方法虽然简单直观,但效率相对较低。对于每一个要判断的数n,都需要从 2 到n - 1进行遍历检查,其时间复杂度大致为O(n的2次方)(这里的n是要判断的数的范围,在本程序中是 100)。因为对于每个数都要进行n - 1次左右的除法运算来判断是否能被整除。

 

在实际应用中,如果要判断更大范围的数是否为素数,通常会采用更高效的算法,比如埃拉托斯特尼筛法等,这些算法可以大大提高判断素数的效率。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ReactPress与WordPress:一场内容管理系统的较量

ReactPress Github项目地址&#xff1a;https://github.com/fecommunity/reactpress WordPress官网&#xff1a;https://wordpress.org/ ReactPress与WordPress&#xff1a;一场内容管理系统的较量 在当今数字化时代&#xff0c;内容管理系统&#xff08;CMS&#xff09;已成为…

DevExpress WinForms中文教程:Data Grid - 如何绑定到实体框架数据源?

在本教程中&#xff0c;您将学习如何将DevExpress WinForms的网格控件绑定到实体框架数据源、如何使用数据注释属性来更改网格显示和管理数据的方式&#xff0c;以及如何将单元格值更改发送回数据源。 P.S&#xff1a;DevExpress WinForms拥有180组件和UI库&#xff0c;能为Wi…

使用多种机器学习调参模型进行二分类建模的全流程,代做分析辅导

使用多种机器学习调参模型进行二分类建模的全流程教程 机器学习全流程分析各个模块用到的总的参数文件 0. 分析参数文件 参数文件名称&#xff1a;total_analysis_params_demo.xlsx &#xff0c;很多分析模块都是这个总的参数文件&#xff0c;我的这个总的参数文件如果有更新…

材质(一)

描述&#xff1a; 材质蓝图&#xff0c;蓝图可以这么定义&#xff0c;是一种数据结构&#xff0c;是一种带有流水线的模糊的数据结构&#xff0c; 材质蓝图也是一种蓝图。 示例操作:

SCI论文数据可视化的在线网址

目录 SCI论文数据可视化的在线网址 EVenn(Evenn):免费 SCI论文数据可视化的在线网址 数据可视化的在线网址,以下是一些值得推荐的资源: ImageGP(ImageGP | ImageGP):该平台可以在线生成常见的线图、柱状图、散点图、箱线图、集合图、热图和直方图等。用户只需粘贴数…

电子应用产品设计方案-4:基于物联网和人工智能的温度控制器设计方案

一、概述 本温度控制器旨在提供高精度、智能化、远程可控的温度调节解决方案&#xff0c;适用于各种工业和民用场景。 二、系统组成 1. 传感器模块 - 采用高精度的数字式温度传感器&#xff0c;如 TMP117&#xff0c;能够提供精确到 0.01C 的温度测量。 - 配置多个传感器分布在…

5G的发展演进

5G发展的驱动力 什么是5G [远程会议&#xff0c;2020年7月10日] 在来自世界各地的政府主管部门、电信制造及运营企业、研究机构约200多名会议代表和专家们的共同见证下&#xff0c;ITU-R WP 5D#35e远程会议宣布3GPP 5G技术&#xff08;含NB-IoT&#xff09;满足IMT-2020 5G技…

人工智能--自然语言处理简介

上一篇&#xff1a;《人工智能模型训练中的数据之美——探索TFRecord》 序言&#xff1a;自然语言处理&#xff08;NLP&#xff09;是人工智能中的一种技术&#xff0c;专注于理解基于人类语言的内容。它包含了编程技术&#xff0c;用于创建可以理解语言、分类内容&#xff0c…

第8章 利用CSS制作导航菜单

8.1 水平顶部导航栏 水平莱单导航栏是网站设计中应用范围最广的导航设计&#xff0c;一般放置在页面的顶部。水平 导航适用性强&#xff0c;几乎所有类型的网站都可以使用&#xff0c;设计难度较低。 如果导航过于普通&#xff0c;无法容纳复杂的信息结构&#xff0c;就需要在…

企望制造ERP系统 drawGrid.action SQL注入致RCE漏洞复现

0x01 产品简介 企望制造ERP系统是一款专为制造企业设计的企业资源计划(ERP)软件,旨在优化企业的资源配置,提高运营效率,并增强企业的竞争力。系统集成了财务管理、生产管理、供应链管理、客户关系管理(CRM)、人力资源管理(HRM)等多个核心功能模块,能够全面覆盖企业的…

基于JDBC的书库系统(MySQL)

一、创建数据库中的表 1、需求 有一张表叫javabook【创建表要求使用sql语句进行】 表中列 bookid 整数自增类型 表中列 bprice 小数类型 表中列 bookname 字符串类型 长度不能小于50 工程和包要求&#xff1a; domain dao …

内置RTK北斗高精度定位的4G执法记录仪、国网供电服务器记录仪

内置RTK北斗高精度定位的4G执法记录仪、国网供电服务器记录仪BD311R 发布时间: 2024-10-23 11:28:42 一、 产品图片&#xff1a; 二、 产品特性&#xff1a; 4G性能&#xff1a;支持2K超高清图传&#xff0c;数据传输不掉帧&#xff0c;更稳定。 独立北…

腾讯音乐2024Q3财报:“稳”是核心,再进一步

11月12日&#xff0c;腾讯音乐娱乐集团&#xff08;以下简称“腾讯音乐”&#xff09;发布了截至2024年9月30日止的第三季度未经审计财务报告&#xff0c;各项核心财务指标均符合市场预期。本季度总收入为70.2亿元&#xff0c;同比增长6.8%&#xff1b;调整后净利润为19.4亿元&…

地宫取宝(摘花生+最长上升子序列)C++

1212. 地宫取宝 - AcWing题库 #include <iostream>using namespace std;const int N 55; const int MOD 1000000007;int w[N][N],f[N][N][13][14]; int n,m,k;int main() {cin >> n >> m >> k;for (int i 1;i < n;i) {for (int j 1;j < m;j)…

2024 年 8 个最佳 API 设计工具图文介绍

8 个最佳 API 设计工具推荐&#xff0c;包括 Apifox、Postman、Swagger、Insomnia、Stoplight、Hoppscotch、RapidAPI和Paw。 详细介绍&#xff1a;2024 年 8 个最佳 API 设计工具推荐

minio 分布式

方案设计 需要5台服务器&#xff0c;一台nginx用作分发请求&#xff0c;4台minio服务器&#xff0c;每个minio服务器上至少2个盘。在这个方法中&#xff0c;我使用了lvm的缓存&#xff0c;在同种固态盘的情况下&#xff0c;可以使读性能提高数倍到十倍&#xff0c;使写性能提高…

kettle开发-Day43-数据对比

前言&#xff1a; 随着数字化的深入&#xff0c;各种系统及烟囱的建立&#xff0c;各系统之间的架构和数据存储方式不同&#xff0c;导致做数据仓库或数据湖时发现&#xff0c;因自建的系统或者非标准化的系统经常存在物理删除而不是软删除。这就延伸出一个问题&#xff0c;经常…

vscode中执行git合并操作需要输入合并commit信息,打开的nano小型文本编辑器说明-

1.前提&#xff1a; VScode中的git组件执行任何合并动作的时候需要提交远程合并的commit信息&#xff0c;然后编辑器自动打开的是nano文本编辑器 2.nano编辑器说明&#xff1a; 1.保存文件&#xff1a;按 Ctrl O&#xff0c;然后按 Enter 来保存文件。 2.退出编辑器&#xf…

Android音视频直播低延迟探究之:WLAN低延迟模式

Android WLAN低延迟模式 Android WLAN低延迟模式是 Android 10 引入的一种功能&#xff0c;允许对延迟敏感的应用将 Wi-Fi 配置为低延迟模式&#xff0c;以减少网络延迟&#xff0c;启动条件如下&#xff1a; Wi-Fi 已启用且设备可以访问互联网。应用已创建并获得 Wi-Fi 锁&a…

如何详细查询全球药品研发的进度信息?

药品的研发进展对于医药研发人员来说&#xff0c;不仅是知识和技能的积累&#xff0c;更是职业精神和价值观的塑造。通过了解药品的研发进展&#xff0c;研发人员可以更好地提高自己的专业知识和技能&#xff0c;激发创新思维&#xff0c;保持专业竞争力&#xff0c;提高研发效…