查找算法与排序算法

查找算法

二分查找 (要求熟练)

// C// 二分查找法(递归实现)
int binarySearch(int *nums, int target, int left, int right)		// left代表左边界,right代表右边界
{if (left > right)	return -1;		// 如果左边大于右边,那么说明找不到,直接返回-1int mid = (left + right) / 2;		// 计算出中间位置的下标if (nums[mid] == target) return mid;	// 如果刚好相等,就返回下标if (nums[mid] > target) return binarySearch(nums, target, left, mid - 1);	// 如果大于,说明肯定不在右边,直接去左边找else return binarySearch(nums, target, mid + 1, right);		// 如果小于,说明肯定不在左边,直接去右边找
}

更多内容

七大查找算法 (C语言实现):https://www.cnblogs.com/maybe2030/p/4715035.html

排序算法

基础排序

排序算法最好情况最坏情况空间复杂度稳定性
冒泡排序O(n)O(n^2)O(1)稳定
插入排序O(n)O(n^2)O(1)稳定
选择排序O(n^2)O(n^2)O(1)不稳定

冒泡排序 (要求熟练)

基本介绍

  • 冒泡排序的核心就是交换,通过不断地进行交换,一点一点将大的元素推向一端,每一轮都会有一个最大的元素排到对应的位置上,最后形成有序。

  • 动画演示:https://visualgo.net/zh/sorting

代码实现

// C#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>// 冒泡排序
void bubbleSort(int* arr, int size)
{int temp;bool ordered = true;	// 我们先假设传进来的数组是有序的for (int i = 0; i < size - 1; i++){for (int j = 0; j < size - 1 - i; j++){if (arr[j] > arr[j + 1])	// 如果没有执行if语句,说明数组确实是本来就有序{ordered = false;temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}if (ordered){printf("该数组本来就有序!\n");return;}}
}// 输出数组中的内容
void show(int* arr, int size)
{for (int i = 0; i < size; i++){printf("%d ", arr[i]);}printf("\n");
}int main()
{// int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };int arr[] = { 7, 3, 5, 9, 2, 0, 6, 1, 4, 8 };int arrSize = 10;show(arr, arrSize);// 冒泡排序bubbleSort(arr, arrSize);show(arr, arrSize);getchar();return 0;
}

插入排序

基本介绍

  • 我们默认第一个是有序状态,剩余的部分我们会挨着遍历,然后将其插到前面对应的位置上去

  • 每轮排序会从后面依次选择一个元素,与前面已经处于有序的元素,从后往前进行比较,直到遇到一个不大于当前元素的的元素,将当前元素插入到此元素的前面

  • 动画演示:https://visualgo.net/zh/sorting

代码实现

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>// 插入排序
void insertSort(int* arr, int size)
{int current, j;for (int i = 1; i < size; i++){current = arr[i];j = i;while (j > 0 && arr[j - 1] > current){arr[j] = arr[j - 1];	// 找的过程中需要不断进行后移操作,把位置腾出来j--;}arr[j] = current;}
}// 输出数组中的内容
void show(int* arr, int size)
{for (int i = 0; i < size; i++){printf("%d ", arr[i]);}printf("\n");
}int main()
{int arr[] = { 7, 3, 5, 9, 2, 0, 6, 1, 4, 8 };int arrSize = 10;show(arr, arrSize);// 插入排序insertSort(arr, arrSize);show(arr, arrSize);getchar();return 0;
}

选择排序

基本介绍

  • 每轮排序会从后面的所有元素中寻找一个最小的元素出来,然后与已经排序好的下一个位置进行交换

  • 动画演示:https://visualgo.net/zh/sorting

代码实现

// C#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>// 选择排序
void selectSort(int* arr, int size)
{for (int i = 0; i < size - 1; i++){int min = i;	// arr[min]能访问最小元素// 内部循环for (int j = i + 1; j < size; j++){if (arr[min] > arr[j])	min = j;	// 更新下标}// 经过内部循环后,此时 arr[min] 访问的一定是最小元素int temp = arr[i];arr[i] = arr[min];arr[min] = temp;}
}// 选择排序优化版:双选择排序
// 1. 交换函数
void swap(int* a, int* b)
{int temp = *a;*a = *b;*b = temp;
}// 2. 双选择排序
void twoSelectSort(int* arr, int size)
{// 设定最开始的范围为[0, size - 1], 每循环一轮后,left++, right--,缩小范围int left = 0, right = size - 1;// 每循环一轮,就缩小范围while (left < right){int min = left, max = right;	// 假定当前范围内,最小数的下标为左边界的那一个,最大数的下标为右边界的那一个for (int i = left; i <= right; i++)		// 从当前的左边界一直遍历到当前的有边界,遍历过程中,记录最小数和最大数的下标{if (arr[i] < arr[min])	min = i;	// arr[i] 在不断变化的过程中,如果小于我们最开始假定的 arr[min] 最小值,就马上更新当前最小值的下标 min,从而记录了当前最新的最小值 arr[min]if (arr[i] > arr[max])	max = i;	// arr[i] 在不断变化的过程中,如果小于我们最开始假定的 arr[max] 最大值,就马上更新当前最小值的下标 max,从而记录了当前最新的最大值 arr[max]}// for 循环一轮过后,当前 arr[min] 和 arr[max] 存放的就是,这一轮 [left, right] 范围中的最小值和最大值swap(&arr[max], &arr[right]);		// 让当前最大值 arr[max] 和 我们假定的最大值 arr[right] 进行交换if (min == right)	min = max;		// 如果上面的要被交换的 arr[right] 刚好是本轮的最小值 arr[min],那么发生交换后,arr[max] 里面存放的才是我们最开始的 arr[min],所以我们需要更新 minswap(&arr[min], &arr[left]);		// 让当前最小值 arr[min] 和 我们假定的最小值 arr[left] 进行交换left++;		// 缩小范围right--;	// 缩小范围}
}// 输出数组中的内容
void show(int* arr, int size)
{for (int i = 0; i < size; i++){printf("%d ", arr[i]);}printf("\n");
}int main()
{int arr[] = { 7, 3, 5, 9, 2, 0, 6, 1, 4, 8};int arrSize = 10;show(arr, arrSize);// 选择排序// selectSort(arr, arrSize);	// 选择排序twoSelectSort(arr, arrSize);	// 双选择排序show(arr, arrSize);getchar();return 0;
}

进阶排序

排序算法最好情况最坏情况空间复杂度稳定性
快速排序O(nlogn)O(n^2)O(nlogn)不稳定
希尔排序O(n^1.3)O(n^2)O(1)不稳定
堆排序O(nlogn)O(nlogn)O(1)不稳定

快速排序 (要求熟练)

基本概念

  • 快速排序是冒泡排序的进阶版本

  • 在冒泡排序中,进行元素的比较和交换是在相邻元素之间进行的,元素每次交换只能移动一个位置,所以比较次数和移动次数较多,效率相对较低

  • 而在快速排序中,元素的比较和交换是从两端向中间进行的,较大的元素一轮就能够交换到后面的位置,而较小的元素一轮就能交换到前面的位置,元素每次移动的距离较远,所以比较次数和移动次数较少,就像它的名字一样,速度更快

代码实现

图1:

在这里插入图片描述

图2:

在这里插入图片描述

代码:

// C#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>// 快速排序
void quickSort(int* arr, int start, int end)
{// 结束递归if (start >= end)	return;// ------------------------ 快速排序算法逻辑主体 ------------------------int leftPointer = start, rightPointer = end;	// 定义一对左右指针,方便待会标记int reference = arr[leftPointer];				// 选定参考值while (leftPointer < rightPointer)		// 两个指针不相遇才能进行循环{// 从右边开始,一直向左边寻找,直到找到比参考值小的数,将这个数移动到 arr[leftPointer]while (leftPointer < rightPointer && arr[rightPointer] >= reference)	rightPointer--;arr[leftPointer] = arr[rightPointer];// 从左边开始,一直向右边寻找,直到找到比参考值大的数,将这个数移动到 arr[rightPointer]while (leftPointer < rightPointer && arr[leftPointer] <= reference)		leftPointer++;arr[rightPointer] = arr[leftPointer];}// 退出循环,说明两个指针相遇,说明此时 leftPointer = rightPointerarr[leftPointer] = reference;	// 或者 arr[rightPointer] = reference;	两个都一样// 继续递归下去quickSort(arr, start, leftPointer - 1);quickSort(arr, rightPointer + 1, end);
}// 输出数组中的内容
void show(int* arr, int size)
{for (int i = 0; i < size; i++){printf("%d ", arr[i]);}printf("\n");
}int main()
{int arr[] = { 7, 3, 5, 9, 2, 0, 6, 1, 4, 8 };int arrSize = 10;show(arr, arrSize);// 快速排序quickSort(arr, 0, arrSize - 1);show(arr, arrSize);getchar();return 0;
}

希尔排序

基本介绍

  • 希尔排序又叫缩小增量排序

  • 希尔排序是插入排序的进阶版本

  • 希尔排序对插入排序进行改进,它会对整个数组按照步长进行分组,优先比较距离较远的元素

  • 这个步长是由一个增量序列来定的,这个增量序列十分重要

代码实现

// C#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>// 希尔排序
void shellSort(int arr[], int size) {int delta = size / 2;while (delta >= 1) {// 这里依然是使用之前的插入排序,不过此时需要考虑分组了for (int i = delta; i < size; ++i) {		// 我们需要从delta开始,因为前delta个组的第一个元素默认是有序状态int j = i, tmp = arr[i];		// 这里依然是把待插入的先抽出来while (j >= delta && arr[j - delta] > tmp) {// 注意这里比较需要按步长往回走,所以说是j - delta,此时j必须大于等于delta才可以,如果j - delta小于0说明前面没有元素了arr[j] = arr[j - delta];j -= delta;}arr[j] = tmp;}delta /= 2;		// 分组插排完事之后,重新计算步长}
}// 输出数组中的内容
void show(int* arr, int size)
{for (int i = 0; i < size; i++){printf("%d ", arr[i]);}printf("\n");
}int main()
{int arr[] = { 7, 3, 5, 9, 2, 0, 6, 1, 4, 8 };int arrSize = 10;show(arr, arrSize);// 快速排序shellSort(arr, arrSize);show(arr, arrSize);getchar();return 0;
}

堆排序

基本认识

  • 堆排序也是选择排序的一种,但是它能够比直接选择排序更快
  • 对于一棵完全二叉树,树中父亲结点都比孩子结点小的我们称为小根堆(小顶堆),树中父亲结点都比孩子结点大则是大根堆
  • 得益于堆是一棵完全二叉树,我们可以很轻松地使用数组来进行表示

在这里插入图片描述

// C#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>// 输出数组中的内容
void show(int* arr, int size)
{for (int i = 0; i < size; i++){printf("%d ", arr[i]);}printf("\n");
}// 堆
typedef int E;
typedef struct MinHeap {E* arr;int size;int capacity;
} *Heap;// 初始化堆
bool initHeap(Heap heap) {heap->size = 0;heap->capacity = 10;heap->arr = (E*)malloc(sizeof(E) * heap->capacity);return heap->arr != NULL;
}// 插入元素
bool insert(Heap heap, E element) {if (heap->size == heap->capacity) return false;int index = ++heap->size;while (index > 1 && element < heap->arr[index / 2]) {heap->arr[index] = heap->arr[index / 2];index /= 2;}heap->arr[index] = element;return true;
}// 删除元素
E remove(Heap heap) {E max = heap->arr[1], e = heap->arr[heap->size--];int index = 1;while (index * 2 <= heap->size) {int child = index * 2;if (child < heap->size && heap->arr[child] > heap->arr[child + 1])child += 1;if (e <= heap->arr[child]) break;else heap->arr[index] = heap->arr[child];index = child;}heap->arr[index] = e;return max;
}int main() {int arr[] = { 3, 5, 7, 2, 9, 0, 6, 1, 8, 4 };int arrSize = 10;show(arr, arrSize);struct MinHeap heap;    // 创建堆initHeap(&heap);		// 初始化堆for (int i = 0; i < 10; ++i){insert(&heap, arr[i]);		// 直接把乱序的数组元素挨个插入}for (int i = 0; i < 10; ++i){arr[i] = (int)remove(&heap);		// 然后再一个一个拿出来,就是按顺序的了}show(arr, arrSize);getchar();return 0;
}

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

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

相关文章

初始化Linux或者Mac下Docker运行环境

文章目录 1 Mac下安装Docker2 Linux下安装Docker2.1 确定Linux版本2.2 安装Docker2.3 配置加速镜像 3 Docker安装校验4 安装docker-compose4.1 直接下载二进制文件4.2 移动二进制文件到系统路径4.3 设置可执行权限4.4 验证安装 1 Mac下安装Docker mac 安装 docker 还是比较方便…

配置Zephyr编译环境

安装chocolatey 以管理员身份运行PowerShell&#xff0c;然后在PowerShell下执行以下命令&#xff0c;安装chocolatey。 Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol [System.Net.ServicePointManager]::Securi…

【深度学习实战(32)】模型结构之解耦头(de-coupled head)与耦合头(coupled head)

一、传统耦合头局限性 传统的检测模型&#xff0c;如YOLOv3和YOLOv4&#xff0c;使用的是单一的检测头&#xff0c;它同时预测目标类别和框的位置。然而&#xff0c;这种设计存在一些问题。首先&#xff0c;将类别预测和位置预测合并在一个头中&#xff0c;可能导致一个任务的…

Wireshark CLI | 过滤包含特定字符串的流

问题背景 源自于和朋友的一次技术讨论&#xff0c;关于 Wireshark 如何查找特定字符串所在的 TCP 流&#xff0c;原始问题如下&#xff1a; 仔细琢磨了下&#xff0c;基于我对 Wireshark 的使用经验&#xff0c;感觉一步到位实现比较困难&#xff0c;所以想着说用 Wireshark C…

旅游系列之:庐山美景

旅游系列之&#xff1a;庐山美景 一、路线二、住宿二、庐山美景 一、路线 庐山北门乘坐大巴上山&#xff0c;住在上山的酒店东线大巴游览三叠泉&#xff0c;不需要乘坐缆车&#xff0c;步行上下三叠泉即可&#xff0c;线路很短 二、住宿 长江宾馆庐山分部 二、庐山美景

Photoshop中图像编辑的基本操作

Photoshop中图像编辑的基本操作 Photoshop中调整图像窗口大小Photoshop中辅助工具的使用网格的使用标尺的使用注释工具的使用 Photoshop中置入嵌入式对象Photoshop中图像与画布的调整画布大小的修改画布的旋转图像尺寸的修改 Photoshop中撤销与还原采用快捷键进行撤销与还原采用…

机器学习之基于Jupyter多种混合模型的糖尿病预测

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着现代生活方式的改变&#xff0c;糖尿病的患病率在全球范围内呈现上升趋势。糖尿病是一种慢性代谢…

上位机图像处理和嵌入式模块部署(树莓派4b使用lua)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 lua是一个脚本语言&#xff0c;比c语言开发容易&#xff0c;也没有python那么重&#xff0c;整体使用还是非常方便的。一般当成胶水语言进行开发&a…

【Hadoop】--基于hadoop和hive实现聊天数据统计分析,构建聊天数据分析报表[17]

目录 一、需求分析 1、背景介绍 2、目标 3、需求 4、数据内容 5、建库建表 二、ETL数据清洗 1、数据问题 2、需求 3、实现 4、扩展概念&#xff1a;ETL 三、指标计算 1、指标1&#xff1a;统计今日消息总量 2、指标2&#xff1a;统计每小时消息量、发送量和接收用…

哥白尼高程Copernicus DEM下载(CSDN_20240505)

哥白尼数字高程模型(Copernicus DEM, COP-DEM)由欧洲航天局(European Space Agency, 简称ESA或欧空局)发布&#xff0c;全球范围免费提供30米和90米分辨率DEM。COP-DEM是数字表面模型(DSM)&#xff0c;它表示地球表面(包括建筑物、基础设施和植被)的高程。COP-DEM是经过编辑的D…

循环神经网络模块介绍(Pytorch 12)

到目前为止&#xff0c;我们遇到过两种类型的数据&#xff1a;表格数据和图像数据。对于图像数据&#xff0c;我们设计了专门的卷积神经网络架构(cnn)来为这类特殊的数据结构建模。换句话说&#xff0c;如果我们拥有一张图像&#xff0c;我们 需要有效地利用其像素位置&#xf…

算法课程笔记——蓝桥云课第六次直播

&#xff08;只有一个数&#xff0c;或者因子只有一个&#xff09;先自己打表&#xff0c;找找规律函数就是2的n次方 异或前缀和 相等就抵消 先前缀和再二分

【Python】机器学习之Sklearn基础教程大纲

机器学习之Sklearn基础教程大纲 1. 引言 机器学习简介Scikit-learn&#xff08;Sklearn&#xff09;库介绍安装和配置Sklearn 2. 数据预处理 2.1 数据加载与查看 - 加载CSV、Excel等格式的数据- 查看数据的基本信息&#xff08;如形状、数据类型等&#xff09;2.2 数据清洗…

本地部署大模型ollama+docker+open WebUI/Lobe Chat

文章目录 大模型工具Ollama下载安装运行Spring Ai 代码测试加依赖配置写代码 ollama的web&Desktop搭建部署Open WebUI有两种方式Docker DesktopDocker部署Open WebUIDocker部署Lobe Chat可以配置OpenAI的key也可以配置ollama 大模型的选择 本篇基于windows环境下配置 大模型…

翔云优配恒生指数涨1.85%、恒生科技指数涨3.74% 小鹏汽车涨超8%

5月3日港股开盘&#xff0c;恒生指数涨1.85%&#xff0c;报18543.3点&#xff0c;恒生科技指数涨3.74%&#xff0c;报4009.96点&#xff0c;国企指数涨2.23%&#xff0c;报6580.81点&#xff0c; 翔云优配是一家领先的在线投资平台,提供全球范围内的股票、期货、基金等交易服务…

小程序引入 Vant Weapp 极简教程

一切以 Vant Weapp 官方文档 为准 Vant Weapp 官方文档 - 快速入手 1. 安装nodejs 前往官网下载安装即可 nodejs官网 安装好后 在命令行&#xff08;winr&#xff0c;输入cmd&#xff09;输入 node -v若显示版本信息&#xff0c;即为安装成功 2. 在 小程序根目录 命令行/终端…

C++类的小结

1、类定义 使用class关键字定义类。 类名通常以大写字母开头&#xff0c;以符合命名规范。 类包含成员变量&#xff08;也称为属性或数据成员&#xff09;和成员函数&#xff08;也称为方法或行为&#xff09;。 class MyClass { public: int x; // 数据成员 void setX…

【Gateway远程开发】0.5GB of free space is necessary to run the IDE.

【Gateway远程开发】0.5GB of free space is necessary to run the IDE. 报错 0.5GB of free space is necessary to run the IDE. Make sure that there’s enough space in following paths: /root/.cache/JetBrains /root/.config/JetBrains 原因 下面两个路径的空间不…

【OpenNJet下一代云原生之旅】

OpenNJet下一代云原生之旅 1、OpenNJet的定义OpenNJet架构图 2、OpenNJet的特点性能无损动态配置灵活的CoPilot框架支持HTTP/3支持国密企业级应用高效安全 3、OpenNJet的功能特性4、OpenNJet的安装使用编译安装配置yum源创建符号连接修改配置编译 5、通过 OpenNJet 部署 WEB SE…

基于OpenCv的图像特征点检测

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…