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分析
- 时间复杂度分析
- 最好情况:当输入的数组已经是有序的情况下,冒泡排序只需要进行一轮比较,没有元素交换操作。此时时间复杂度为,其中
n
是数组的长度。- 最坏情况:当输入的数组是逆序的情况下,需要进行
n-1
轮比较,每一轮比较的次数逐渐减少,总的比较次数是,时间复杂度为。- 平均情况:时间复杂度也是,因为在平均情况下,数组元素的无序程度介于最好情况和最坏情况之间。
- 空间复杂度分析
- 冒泡排序是一种就地排序算法,它只需要一个额外的临时变量
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; // 先假设未找到,赋值为 -1while (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
,使得程序能够使用printf
、scanf
等函数来进行控制台的输入输出操作。②数组定义与初始化
首先通过
#define
指令定义了一个常量SIZE
来表示数组的长度,这里设置为10
。在
main
函数内部,定义并初始化了一个名为arr
的整数数组,数组元素按照降序排列,从10
到1
。这个数组是后续进行二分查找的对象。③目标数字输入
定义了一个整型变量
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){// 如果能被整除,说明不是素数,标记为0isPrime = 0;break;}}// 如果isPrime为1,说明是素数,输出该数字if (isPrime == 1){printf("%d ", i);}}printf("\n");return 0; }
3.3逻辑
在这个程序中:
- 在
main
函数中,首先定义了两个整型变量i
和j
,分别用于外层循环和内层循环的计数。- 通过
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
次左右的除法运算来判断是否能被整除。在实际应用中,如果要判断更大范围的数是否为素数,通常会采用更高效的算法,比如埃拉托斯特尼筛法等,这些算法可以大大提高判断素数的效率。
相关文章:
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原理 冒泡排序&…...

【Pikachu】XML外部实体注入实战
若天下不定,吾往;若世道不平,不回! 1.XXE漏洞实战 首先写入一个合法的xml文档 <?xml version "1.0"?> <!DOCTYPE gfzq [<!ENTITY gfzq "gfzq"> ]> <name>&gfzq;</name&…...

vue2项目中在线预览csv文件
简介 希望在项目中,在线预览.csv文件,本以为插件很多,结果都只是支持excel(.xls、.xlsx)一到.csv就歇菜。。。 关于文件预览 vue-office:文档、 查看在线演示demo,支持docx、.xlsx、pdf、ppt…...

基于VUE实现语音通话:边录边转发送语言消息、 播放pcm 音频
文章目录 引言I 音频协议音频格式:音频协议:II 实现协议创建ws对象初始化边录边转发送语言消息 setupPCM按下通话按钮时开始讲话,松开后停止讲话播放pcm 音频III 第三库recorderplayer调试引言 需求:电台通讯网(电台远程遥控软件-超短波)该系统通过网络、超短波终端等无线…...
PMP--一、二、三模、冲刺--分类--变更--技巧--特点
文章目录 一模二模三模冲刺14.敏捷--不确定性、风险和生命周期选择14.敏捷--特点--敏捷范围灵活,敏捷拥抱变更14.敏捷--阶段关口--在不同的组织、行业或工作类型中,阶段关口可能被称为阶段审查、阶段门、关键决策点和阶段入口或阶段出口。组织可以通过这…...
CSS Grid 布局实战:从入门到精通
文章目录 前言一、CSS Grid 布局概述1.1 什么是 CSS Grid 布局?1.2 主要特点 二、基本概念2.1 网格容器2.2 网格线2.3 网格轨道2.4 网格区域 三、常用属性3.1 定义网格结构3.2 控制网格项的位置3.3 控制网格间距3.4 自动填充和重复 四、实践案例4.1 项目结构4.2 HTM…...

git创建远程仓库,以gitee码云为例GitHub同理
git远程Remote服务端仓库构建的视频教程在这 Git建立服务端Remote远程仓库,gitee码云例,Github_哔哩哔哩_bilibili 1、登gitee码云/Github 登录 - Gitee.com https://github.com/ (没账号的注册一下就行) 点击如下图位置的创…...
Java爬虫(HttpURLConnection)详解
文章目录 Java爬虫(HttpURLConnection)详解一、引言二、准备工作1、环境配置2、理解HttpURLConnection 三、发送GET请求1、创建URL对象2、打开连接3、设置请求方法4、连接并读取响应5、处理返回的数据 四、发送POST请求1、设置输出2、发送请求体3、读取响…...
基于STM32的智能停车管理系统设计
引言 随着城市汽车保有量的增加,停车难问题日益严重,传统停车管理方式效率低下,无法满足现代化需求。为了解决这一问题,本项目基于STM32微控制器设计了一种智能停车管理系统。系统能够通过传感器实时监测停车位的使用情况&#x…...

【循环神经网络】
循环神经网络(Recurrent Neural Network, RNN)是一类用于处理序列数据的神经网络,擅长处理具有时间依赖或顺序结构的数据。RNN通过循环连接的结构,使得当前时刻的输出可以受之前时刻信息的影响,因此被广泛应用于自然语…...

优选算法 - 4 ( 链表 哈希表 字符串 9000 字详解 )
一:链表 1.1 链表常用技巧和操作总结 1.2 两数相加 题目链接:两数相加 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* …...
CTF-RE 从0到N: windows反调试-获取Process Environment Block(PEB)信息来检测调试
在Windows操作系统中,Process Environment Block (PEB,进程环境块) 是一个包含特定进程信息的数据结构。它可以被用于反调试中 如何获取PEB指针? 在Windows操作系统中,获取PEB指针的常见方法主要有以下几种。: 1. 使…...
STM32开发基础阶段复习
1.使用寄存器方式点亮LED灯的三个步骤是什么? 首先使能RCC_APB2ENR(外设时钟使能寄存器)对应的GPIO端口时钟,即给LED这个外设使能时钟。 配置对应GPIO端口,配置为通用推挽输出,输出速度可以选择最大。 将GPIO端口输…...
搜维尔科技:SenseGlove触觉反馈手套开箱+场景测试
搜维尔科技:SenseGlove触觉反馈手套开箱场景测试 SenseGlove触觉反馈手套开箱场景测试...

在k8s上部署Crunchy Postgres for Kubernetes
目录 一、前言二、安装Crunchy Postgres for Kubernetes三、部署一个简单的postgres集群四、增加pgbouncer五、数据备份六、备份恢复七、postgres配置参数七、数据导入 一、前言 Crunchy Postgres可以帮助我们在k8s上快速部署一个高可用、具有自动备份和恢复功能的postgres集群…...
大模型(LLMs)进阶篇
大模型(LLMs)进阶篇 一、什么是生成式大模型? 生成式大模型(一般简称大模型LLMs)是指能用于创作新内容,例如文本、图片、音频以及视频的一类深度学习模型。相比普通深度学习模型,主要有两点不…...

近几年新笔记本重装系统方法及一些注意事项
新笔记本怎么重装系统? 近几年的新笔记本默认开启了raid on模式或vmd选项,安装过程中会遇到问题,新笔记本电脑重装自带的系统建议采用u盘方式安装,默认新笔记本有bitlocker加密机制,如果采用一键重装系统或硬盘方式安装…...

小程序19-微信小程序的样式和组件介绍
在小程序中不能使用 HTML 标签,也就没有 DOM 和 BOM,CSS 也仅支持部分选择器 小程序提供了 WXML 进行页面结构的编写,WXSS 进行页面的样式编写 WXML 提供了 view、text、image、navigator等标签构建页面结构,小程序中标签称为组件…...

Chrome 浏览器开启打印模式
打开开发者工具ctrl shift p输入print 找到 Emulate CSS print media type...

Git回到某个分支的某次提交
1.切换到需要操作的分支(<branch-name>是分支名称)。 命令如下: git checkout <branch-name> 2.获取代码的提交记录 。命令如下: git log 按q退出当前命令对话。 获取到某次提交或者合并的hash值(下文…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...

《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...