元旦特辑:Note6---选择排序


目录

前言❌

1. 基本思想⚠️

2. 直接选择排序🟢

2.1 思路分析✳️

2.2 代码实现❎

2.2.1 sort.h

2.2.2 sort.c

2.2.3 test.c

2.3 问题解决❇️

2.3.1 sort.c修改

2.4 特性总结✅

3. 堆排序🔵

3.1 代码实现🏧

3.2 特性总结🛜

4. 选择排序和插入排序性能对比🅿️

后语⭕️


前言❌

Hey young fella! Welcome to my channel!  前面一篇博客,我们学习了插入排序的2种实现方法。今天也是类似的,今天我们将一起学习选择排序的2种实现:直接选择排序+堆排序。


1. 基本思想⚠️

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置直到全部待排序的数据元素排完

2. 直接选择排序🟢

2.1 思路分析✳️

目标:实现升序

思路:暴力选取

把数据遍历一遍,依次将最大(小)的,次大(小)的,次次大(小)的放到对应的前三位(每次选取都要遍历一遍)然后重复上述步骤,直到最后就剩下1个数据


当然,我们也可以优化一下:
第一次遍历选出最大的和最小的放到头和尾的位置
第二次遍历选出次大的和次小的放到头+1和尾-1的位置

......

2.2 代码实现❎

2.2.1 sort.h

#pragma once
#include<stdio.h>
#include<stdlib.h>//打印
void PrintArray(int* a, int n);
//直接插入排序
void SelectSort(int* a, int n);

2.2.2 sort.c

#include"sort.h"
//打印
void PrintArray(int* a, int n)
{for (int i = 0; i < n; i++)printf("%d ", a[i]);printf("\n");
}//交换
void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}//直接插入排序
void SelectSort(int* a, int n)
{int begin = 0, end = n - 1,i;while (begin < end){int min = begin, max = begin;//一次排2个min和maxfor (i = begin + 1; i <=end; i++){if (a[i] < a[min])min = i;if (a[i] > a[max])max = i;}Swap(&a[begin], &a[min]);Swap(&a[end], &a[max]);begin++;end--;}
}

2.2.3 test.c

#include"sort.h"
//直接插入排序
void testSelectSort()
{int a[] = { 3,2,6,8,9,7,5,10,1,4 };int n = sizeof(a) / sizeof(int);SelectSort(a, n);PrintArray(a, n);
}
int main()
{testSelectSort();return 0;
}


2.3 问题解决❇️

我们发现,排序结果怎么有点不对呢?5,6的顺序怎么反了?

通过调试,我们发现最后一次排序的时候,交换那里出现了问题:max和begin位置重合了
min和begin交换完之后,排序是正确的;但是,end和max又交换了一次,导致顺序出错

所以,我们需要判断一下max和begin是否重合,重合了就不交换max和end;没重合就交换

2.3.1 sort.c修改

//交换
void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}//直接插入排序
void SelectSort(int* a, int n)
{int begin = 0, end = n - 1,i;while (begin < end){int min = begin, max = begin;//一次排2个min和maxfor (i = begin + 1; i <=end; i++){if (a[i] < a[min])min = i;if (a[i] > a[max])max = i;}Swap(&a[begin], &a[min]);//判断max和begin位置是否重合if (begin != max)Swap(&a[end], &a[max]);begin++;end--;}
}


2.4 特性总结✅

1. 直接选择排序思考非常好理解,但是效率不是很好(后面会性能对比)。实际中很少使用

2. 时间复杂度:O(N^2)

最好的情况下也是O(N^2):接近有序or有序
但是,我们不知道有序还是无序,还是需要遍历并且选出max和min交换--->O(N^2)

3. 空间复杂度:O(1)

4. 稳定性:不稳定

3. 堆排序🔵

之前的博客我们详细介绍过了堆排序的实现,这里就不再详述了,直接上代码。需要详述的小伙伴可以点击下方链接🔗:

Note3---初阶二叉树~~-CSDN博客文章浏览阅读1.1k次,点赞59次,收藏51次。这篇博客,我们一起来了解并学习数据结构中的初阶的二叉树的概念和性质;以及堆和堆堆应用二叉树的知识点和内容比较多,友友们一定要有耐心看完(跳到自己需要的部分也是OK的)。https://blog.csdn.net/2301_79184587/article/details/135033457

3.1 代码实现🏧

3.1.1 sort.h

//堆排序
void HeapSort(int* a, int n);

3.1.2 sort.c

//向下调整
void AdjustDown(int* a, int size, int parent)
{int child = parent * 2 + 1;while (child < size){if (a[child + 1] > a[child] && child + 1 < size)child++;if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = 2 * parent + 1;}elsebreak;}
}//堆排序
void HeapSort(int* a, int n)
{//建大堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}

3.1.3 test.c

//堆排序
void testHeapSort()
{int a[] = { 3,2,6,8,9,7,5,10,1,4 };int n = sizeof(a) / sizeof(int);HeapSort(a, n);PrintArray(a, n);
}
int main()
{testHeapSort();return 0;
}


3.2 特性总结🛜

1. 堆排序使用堆来选数,效率就高了很多。

2. 时间复杂度:O(N*logN)

3. 空间复杂度:O(1)

4. 稳定性:不稳定

4. 选择排序和插入排序性能对比🅿️

// 测试排序的性能对比
void TestOP()
{srand(time(0));const int N = 100000;int* a1 = (int*)malloc(sizeof(int) * N);int* a2 = (int*)malloc(sizeof(int) * N);int* a3 = (int*)malloc(sizeof(int) * N);int* a4 = (int*)malloc(sizeof(int) * N);int* a5 = (int*)malloc(sizeof(int) * N);int* a6 = (int*)malloc(sizeof(int) * N);for (int i = 0; i < N; ++i){a1[i] = rand()+i;a2[i] = a1[i];a3[i] = a1[i];a4[i] = a1[i];a5[i] = a1[i];a6[i] = a1[i];}int begin1 = clock();InsertSort(a1, N);int end1 = clock();int begin2 = clock();ShellSort(a2, N);int end2 = clock();int begin3 = clock();SelectSort(a3, N);int end3 = clock();int begin4 = clock();HeapSort(a4, N);int end4 = clock();int begin5 = clock();//QuickSort(a5, 0, N - 1);int end5 = clock();int begin6 = clock();//MergeSort(a6, N);int end6 = clock();printf("InsertSort:%d\n", end1 - begin1);printf("ShellSort:%d\n", end2 - begin2);printf("SelectSort:%d\n", end3 - begin3);printf("HeapSort:%d\n", end4 - begin4);printf("QuickSort:%d\n", end5 - begin5);printf("MergeSort:%d\n", end6 - begin6);free(a1);free(a2);free(a3);free(a4);free(a5);free(a6);
}
int main()
{TestOP();return 0;
}


我们发现,10万数据的时候,堆排序和希尔排序相差不大;100万个数据时,希尔排序的时间复杂度远超于堆排序的时间复杂度

后语⭕️

今天,我们学习了选择排序的实现和性能对比以及他们的特性总结。希望小伙伴们自己也可以练习一下,加强记忆和理解。

下一篇博客,我们将一起学习交换排序的相关知识点!请大家多多期待🙏

本次的分享到这里就结束了!!!

PS:小江目前只是个新手小白。欢迎大家在评论区讨论哦!有问题也可以讨论的!期待大家的互动!!!

公主/王子殿下,请给我点赞👍+收藏⭐️+关注➕(这对我真的很重要!!!


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

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

相关文章

神经元科技发布AI agent—“萨蔓莎”

今天神经元科技发布AI agent—“萨蔓莎“&#xff08;Samantha &#xff09;&#xff01; 取名“萨蔓莎”&#xff0c;是来自于一部讲述AI的电影《HER》。 电影讲述的是电影讲述男子西奥多汤布里&#xff08;Theodore Twombly&#xff0c;饰&#xff09;与拟人化萨曼莎&#…

mysql2pgsql

使用pgloader进行迁移 pgloader是一个强大的数据迁移工具&#xff0c;专为将不同数据库之间的数据迁移到PostgreSQL而设计。它支持从MySQL到PostgreSQL的迁移&#xff0c;并提供了一种简单且灵活的方式来转移数据。 安装pgloader 使用pgloader迁移数据 1、命令行方式 2、脚…

【AI】注意力机制与深度学习模型

目录 一、注意力机制 二、了解发展历程 2.1 早期萌芽&#xff1a; 2.2 真正意义的注意力机制&#xff1a; 2.3 2015 年及以后&#xff1a; 2.4 自注意力与 Transformer&#xff1a; 2.5 BERT 与预训练模型&#xff1a; 三、基本框架 1. 打分函数&#xff08;Score Fun…

Vue常见面试问答

vue响应式数据 vue2 Vue2 的对象数据是通过 Object.defineProperty 对每个属性进行监听&#xff0c;当对属性进行读取的时候&#xff0c;就会触发 getter&#xff0c;对属性进行设置的时候&#xff0c;就会触发 setter。 /** * 这里的函数 defineReactive 用来对 Object.def…

如何正确使用docker搭建redis服务器,安装gcc和make以及出现错误时的解决办法

搭建redis服务器 目录 搭建redis服务器 &#xff08;1&#xff09;开启docker&#xff0c;并查看是否开启成功 &#xff08;2&#xff09;启动上面创建的ssrf容器&#xff0c;并进入ssrf容器 &#xff08;3&#xff09;进入opt&#xff0c;然后下载redis-5.0.5.tar.gz &a…

GitHub Copilot 快速入门

一简介 GitHub Copilot是一个AI编程助手&#xff0c;它能够为开发者提供代码建议和自动完成功能。Copilot使用自然语言处理技术来理解代码的语义&#xff0c;并根据上下文提供智能化的代码建议。通过使用Copilot&#xff0c;开发者可以提高编码效率&#xff0c;减少错误率&…

Apache SSI 远程命令执行漏洞

一、环境搭建 二、访问upload.php 三、写shell <!--#exec cmd"id" --> 四、访问 如图所示&#xff0c;即getshell成功&#xff01;​

Zookeeper-Zookeeper应用场景实战

1. Zookeeper Java客户端实战 ZooKeeper应用的开发主要通过Java客户端API去连接和操作ZooKeeper集群。 可供选择的Java客户端API有&#xff1a; ZooKeeper官方的Java客户端API。 第三方的Java客户端API&#xff0c;比如Curator。 ZooKeeper官方的客户端API提供了基本的操作…

宝塔部署flask添加ssl即https

在宝塔部署flask的步骤我已经写了一篇博客:宝塔部署flask项目-CSDN博客 之前说如果出现找不到application错误: spawned uWSGI http 1 (pid: 3116) --- no python application found, check your startup logs for errors --- [pid: 3114|app: -1|req: -1/1] 127.0.0.1 () {6…

java 什么是变量和字面量?

什么是变量&#xff0c;怎么理解的&#xff1f; 变量其实就是内存当中存储数据的最基本的单元。 一个存储数据的盒子&#xff0c;一个存储数据的单元。 什么是字面量&#xff0c;怎么理解&#xff1f; 整数型字面量&#xff0c;浮点型的字面量&#xff0c;布尔类型字面量&#…

sklearn学习的一个例子用pycharm jupyter

环境 运行在jupyter 进行开发。即一个WEB端的开发工具。能适时显示开发的输出。后缀用的是ipynb.pycharm也可以支持。但也要提示按装jupyter. 或直接用andcoda 这里我们用pycharm进行项目创建 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jupyterlab pip ins…

API服务的快速搭建和测试

API服务的快速搭建和测试 使用Python的FastAPI迅速搭建一个简单API from fastapi import FastAPI, Request from transformers import AutoTokenizer, AutoModel import uvicorn, json, datetime import torch# 设置CUDA设备信息 DEVICE "cuda" DEVICE_ID "0…

在vim中映射类似于Windows编辑器的快捷键

vim编辑器的历史比较久&#xff0c;继承于vi&#xff0c;这个编辑器就更早了。可能拜于年代所赐&#xff0c;里面的快捷键设计似乎不是那么“现代化”&#xff0c;和很多现在的编辑器的热键设计出入很大&#xff0c;里面的命令更不是一般人能记得住的。 我一直知道vim可以rema…

QT 利用开源7z 实现解压各种压缩包,包括进度条和文件名的显示(zip,7z,rar,iso等50多种格式)

想做一个winRAR一样的解压软件吗?很简单,利用开源的7z库就能实现。我看网上其他人说的方法不敢苟同,误人子弟。以前自己在项目中使用过7z,这次又有需要,就想记录下来。如果你研究过如何用7z的话,一定知道7z的每一个GUID都代表了一种格式,50多种GUID也就有50多个格式,最…

uniapp打包Android、Ios、微信小程序

首先我们需要在我们的代码中&#xff0c;把我们所要用到的配置信息配置好&#xff0c;在检查一下我们测试的内容是否有打开&#xff08;取消注释&#xff09;&#xff0c;在检查一下我们的版本信息是否正确&#xff0c;查看一下接口ip是否是正式线 这里的配置信息一定要配置好…

epoll并发编程

epoll并发编程 epoll并发编程背景知识epoll 的特点epoll 的工作原理epoll 和 select/poll 的区别 epoll并发服务器思路重点代码分析git地址参考书目 epoll并发编程背景知识 epoll 是 Linux 中用于处理大量文件描述符的 I/O 事件通知机制。在传统的 I/O 模型中&#xff0c;一般…

Screenshot-to-code开源项目mac上实践

github上的开源项目&#xff0c;看介绍可以将设计ui图片转换为 HTML 和 CSS 源码地址&#xff1a; GitCode - 开发者的代码家园 我的mac安装了2.7和3.11&#xff0c;就用3吧直接上代码 安装 pip3 install keras tensorflow pillow h5py jupyter 报错 ERROR: Could not in…

Linux驱动开发之Linux内核中的中断处理与等待队列以及相关API和例程分析

目录 中断的特点 Linux中的中断类型 相关API函数 gpio_to_irq() enable_irq() disable_irq() request_irq() free_irq() 中断的使用 等待队列 DECLARE_WAIT_QUEUE_HEAD() wait_event_interruptible() wake_up_interruptible() 中断相关例程 例程分析 源码分享 …

linux实用技巧:ubuntu18.04安装samba服务器实现局域网文件共享

Ubuntu安装配置Samba服务与Win10共享文件 Chapter1 Ubuntu18.04安装配置Samba服务与Win10共享文件一、什么是Samba二、安装Samba1、查看是否有安装samba2、安装samba 三、配置Samba服务1、创建共享目录&#xff08;以samba_workspaces为例&#xff09;2、为samba设置登录用户3、…

独立站的个性化定制:提升用户体验的关键

随着电子商务的竞争加剧&#xff0c;用户体验成为了企业赢得市场的关键因素之一。独立站作为企业品牌形象和产品展示的重要平台&#xff0c;其个性化定制的程度直接影响着用户体验。本文将探讨独立站的个性化定制如何提升用户体验&#xff0c;并通过代码示例说明实现个性化定制…