【数据结构】插入排序、选择排序、冒泡排序、希尔排序、堆排序

前言:生活中我们总是会碰到各种各样的排序,今天我们就对部分常用的排序进行总结和学习,今天的内容还是相对比较简单的一部分,各位一起加油哦!

💖 博主CSDN主页:卫卫卫的个人主页 💞
👉 专栏分类:数据结构 👈
💯代码仓库:卫卫周大胖的学习日记💫
💪关注博主和博主一起学习!一起努力!
在这里插入图片描述


插入排序

插入排序:我们可以通俗的理解成将一个数记录下来按其数值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。(由于动图画的实在太过于繁琐博主就画了一半,请见谅)
请添加图片描述

代码思路:由此图我们可以知道,我们用一个tmp记录后面一个元素,如果后面的比前面的小,就让前面的元素逐一和他比较并往后走,如果碰到比他小的就停下来插入到此位置。(不理解的话可以理解成我们平常玩的斗地主的牌,拿一张牌插到应该有的位置)。


代码实现

void InsertSort(int* a, int n)//插入排序
{for (int i = 0; i < n - 1; i++)//升序{int end = i;int tmp = a[end + 1];//保存后一个while (end >= 0){if (tmp < a[end])//前一个大于后一个,让大的全部往后走{a[end + 1] = a[end];end--;}else{break;	}}a[end + 1] = tmp;//在把小的放在此时的位置}
}

测试函数:

void Test_InsertSort()
{int a[] = { 1,2,30,0,99,1,7,8,2,11,0,3,13 };InsertSort(a, sizeof(a) / sizeof(a[0]));PrintArray(a, sizeof(a) / sizeof(a[0]));
}

排序结果:
在这里插入图片描述


希尔排序

希尔排序:我们可以通俗的把待排的序列看成若干个子序列,然后对其分别进行直接插入排序,最后在对全部进行一次排序即可。(如下图所示)
在这里插入图片描述


我们可以理解成gap>1是预排序,目的是让它接近有序
gap == 1是直接插入排序,目的是让它有序。但是记住最后一定要让gap最后一次排序为1
代码思路:我们可以把每次排序写成一次插入排序,然后最后一让其间距不断的变化直到最后一次全部排序完成。
代码实现:

void ShellSort(int* a, int n)//希尔排序 
{int gap = n;while (gap){gap = gap / 2 ;for (int i = 0; i < n - gap; i++)//升序{int end = i;int tmp = a[end + gap];//保存后一个while (end >= 0){if (tmp < a[end])//前一个大于后一个,让大的全部往后走{a[end + gap] = a[end];end = end -gap;}else{break;}}a[end + gap] = tmp;//在把小的放在此时的位置}}
}

函数测试

void Test_ShellSort()
{int a[] = { 1,2,30,0,99,1,7,8,2,11,0,3,13 };ShellSort(a, sizeof(a) / sizeof(a[0]));PrintArray(a, sizeof(a) / sizeof(a[0]));
}

运行结果:
在这里插入图片描述


冒泡排序

冒泡排序:也是我们所碰到的最简单的一种排序,这种排序的思想是十分简单的,我们可以理解成每一趟找到序列中最大的一个或最小的元素,排序到序列的最左边(右边),然后排序序列的有效次数趟即可排序完成(如下图)。
请添加图片描述

代码实现:

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}void BubbleSort(int* a, int n)//冒泡排序
{int i = 0;for (int j = 0; j < n - 1; j++){for (i = 0; i < n - j -1; i++)//每一趟找到一个最大的{if (a[i] < a[i + 1]){Swap(&a[i], &a[i + 1]);}}}
}

函数测试:

void Test_BubbleSort()
{int a[] = { 1,2,30,0,99,1,7,8,2,11,0,3,13 };BubbleSort(a, sizeof(a) / sizeof(a[0]));PrintArray(a, sizeof(a) / sizeof(a[0]));
}

运行结果
在这里插入图片描述


选择排序

选择排序:我们现在一组有序序列中找到最大(最小)和第一个位置交换,然后再找次大的和第二个交换以此类推,最后我们即可得到一个有序序列。(如下图所示)
请添加图片描述


代码实现

void SelectSort(int*a ,int n)//选择排序
{//现在数组中找到最小的,然后和第一个位置交换//再找到次小的,和第二个位置交换int min = 0;for (int i = 0; i < n - 1 ; i++){min = i;//最小的数的下标for (int j = i; j < n; j++){if (a[min] > a[j])//找到最小位置的下标{min = j;}}if(min != i)Swap(&a[i], &a[min]);}
}

测试函数

void Test_SelectSort()
{//int a[] = { 1,2,30,0,99,1,7,8,2,11,0,3,13 };int a[] = { 1,0,0,0,99,1,7,8,2,9,0,3,0 };SelectSort(a, sizeof(a) / sizeof(a[0]));PrintArray(a, sizeof(a) / sizeof(a[0]));}

运行结果:
在这里插入图片描述


但是上面这种方法我们一共要找n-1次,我们思考一下每一次查找的过程中,如果我们每次一起查找最大的和最小的,那我们不就提高了一倍的效率。所以我们只需要再引入一个max变量来帮助我们再记录一下这个值即可。
代码实现

void SelectSort_best(int* a, int n)//选择排序
{int begin = 0;int end = n - 1;while (begin < end){int max = begin;int min = begin;int i = 0;for (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]);if (begin == max)//防止最大的和最小的是相同的{max = min;}Swap(&a[end], &a[max]);begin++;end--;}
}

运行结果依然和前面的相同,这里就不做更多的阐述了。


堆排序

堆排序:前面我们讲了的模拟实现,我们知道堆的父亲结点一定比它的孩子结点大(小),因此我们可以充分的利用这一点来进行排序。

  1. 首先我们们将数组中的元素,想象成一个堆,将其中的父亲结点全部向下调整。(如下图)在这里插入图片描述
  2. 根据我们模拟建立的大堆或者小堆,将其堆顶元素和堆尾进行交换,因此我们可以得到一个最大(最小的元素)再堆底,然后再通过一个end记录尾部,交换一次减减一次,以此循环到end为0的时候即堆中所有元素也排序完成。(如下图所示)
    在这里插入图片描述

代码实现:

void AdjustDown(int* a, int size, int parent)//向下调整
{assert(a);int child = parent * 2 + 1;//找到第一个孩子while (child < size){//看俩个孩子谁更小,交小的那个与父亲去比较if (a[child] < a[child + 1] && (child + 1) < size){child += 1;}if (a[parent] < a[child]){Swap(&a[parent], &a[child]);parent = child;//让父亲和儿子往下走child = child * 2 + 1;}else{break;}}
}void HeapSort(int* a, int n)//堆排序
{int i = 0;for (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--;}
}

函数测试:


void Test_HeapSort()
{int a[] = { 20,10,8,2,1,2,7 };HeapSort(a, sizeof(a) / sizeof(a[0]));PrintArray(a, sizeof(a) / sizeof(a[0]));
}

运行结果:
在这里插入图片描述


好啦,今天的内容就到这里啦,下期内容预告【快速排序的模拟实现】-- 四种方式


结语:今天的内容就到这里吧,谢谢各位的观看,如果有讲的不好的地方也请各位多多指出,作者每一条评论都会读的,谢谢各位。


🫵🫵🫵 祝各位接下来好运连连 💞

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

使用Rust发送邮件

SMTP协议与MIME协议 SMTP&#xff08;简单邮件传输协议,Simple Mail Transfer Protocol&#xff09;是一种用于发送和接收电子邮件的互联网标准通信协议。它定义了电子邮件服务器如何相互发送、接收和中继邮件。SMTP 通常用于发送邮件&#xff0c;而邮件的接收通常由 POP&#…

每日一题--------求数字的每⼀位之和

大家好今天的每日一题又来了&#xff0c;有啥不对的请在评论区留言哦 文章目录 目录 文章目录 求数字的每⼀位之和 题⽬描述&#xff1a; 输⼊⼀个整数m&#xff0c;求这个整数m的每⼀位之和&#xff0c;并打印。 一、解题思路 我们可以通过不断获取该整数的个位数&#xff0c…

算法导论复习(七) 动态规划

动态规划一般用来求解最优化问题 设计一个动态规划算法一般有以下四步&#xff1a; 描述一个最优解的结构特征。递归地定义最优解的值。计算最优解的值&#xff0c;通常采用自底向上的方法。利用计算出的信息构造出一个最优解。 钢条切割问题 体现了动态规划的一个重要性质&a…

磁盘管理 :逻辑卷、磁盘配额

一 LVM可操作的对象&#xff1a;①完成的磁盘 ②完整的分区 PV 物理卷 VG 卷组 LV 逻辑卷 二 LVM逻辑卷管理的命令 三 建立LVM逻辑卷管理 虚拟设置-->一致下一步就行-->确认 echo "- - -" > /sys/class/scsi_host/host0/scan;echo "- -…

什么是https证书?

HTTPS证书&#xff0c;也称为SSL&#xff08;Secure Sockets Layer&#xff09;证书或TLS&#xff08;Transport Layer Security&#xff09;证书&#xff0c;是一种数字证书&#xff0c;用于在网络上建立安全的加密连接。它的主要目的是确保在互联网上进行的数据传输的安全性和…

探索Apache Commons Imaging处理图像

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;咱们今天来聊聊图像处理。在这个数字化日益增长的时代&#xff0c;图像处理已经成为了一个不可或缺的技能。不论是社交媒体上的照片编辑&#xff0c;还是专业领域的图像分析&#xff0c;图像处理无处不在。而作为…

HTML网页设计 科幻风格引入页

成品如下 html <!DOCTYPE html> <html><head><meta charset"utf-8"><title>引入页</title><link href"css/引入页.css" type"text/css" rel"stylesheet" /><style>body{background…

【SD】IP-Adapter 进阶 - 同款人物【2】

测试模型&#xff1a;###最爱的模型\flat2DAnimerge_v30_2.safetensors [b2c93e7a89] 原图&#xff1a; 加入 control1 [IP-Adapter] 加入 control 2 [OpenPose] 通过openpose骨骼图修改人物动作。 加入 control 3 lineart 加入cotrol3 …

leaflet学习笔记-地图图层控制(二)

图层介绍 Leaflet的地图图层控件可控制两类图层&#xff1a;一类是底图图层&#xff08;Base Layers&#xff09;&#xff0c;一次只能选择一个图层作为地图的背景图层&#xff0c;即底图图层&#xff0c;在地图图层控件中用单选按钮控制&#xff1b;另一类是覆盖图层&#xff…

[每周一更]-(第44期):GIT版本控制之忽略文件

基础概念 在 Git 中&#xff0c;可以通过 .gitignore 文件来指定不需要纳入版本控制的文件或文件夹&#xff0c;这些被忽略的文件或文件夹不会被提交到仓库中。 在项目根目录下创建一个名为 .gitignore 的文件&#xff0c;并在其中列出需要忽略的文件或文件夹。一些常见的示例…

uniapp的分包使用记录

UniApp的分包是一种将应用代码划分为多个包的技术。分包的核心思想是将不同部分的代码划分为不同的包&#xff0c;按需加载&#xff0c;从而提高应用性能。使用UniApp的条件编译功能&#xff0c;开发人员可以根据需要将代码划分为多个包。每个包都包含一组页面和组件&#xff0…

SpringBoot+ShardingSphereJDBC实战(读写分离,分库分表,垂直拆分、水平拆分)附源码

参考&#xff1a;https://www.51cto.com/article/747736.html https://blog.csdn.net/qq_41581588/article/details/126966665 源码地址&#xff1a;gitgitee.com:jackXUYY/springboot-example.git 读写分离测试 我们启用后缀名为dev的配置文件&#xff0c;如下&#xff0c;…

公司创建百度百科需要哪些内容?

一个公司或是一个品牌想要让自己更有身份&#xff0c;更有知名度&#xff0c;更有含金量&#xff0c;百度百科词条是必不可少的。通过百度百科展示公司的详细信息&#xff0c;有助于增强用户对公司的信任感&#xff0c;提高企业形象。通过百度百科展示公司的发展历程、领导团队…

【网络安全 | 扫描器】御剑安装及使用教程详析

御剑是一款传统的Web网络安全综合检测程序&#xff0c;支持对PHP、JSP、ASPX等文件进行扫描&#xff0c;具备全扫描、网络安全扫描和主机安全扫描能力&#xff0c;方便发现网站漏洞。 文章目录 下载使用教程 本文对御剑的安装及使用教程进行详析 下载 下载地址读者可自行上网…

Keras多分类鸢尾花DEMO

完整的一个小demo&#xff1a; pandas1.2.4 numpy1.19.2 python3.9.2 import numpy as np import pandas as pd import matplotlib.pyplot as plt from pandas import DataFrame from scipy.io import loadmat from sklearn.model_selection import train_test_split impor…

Rhinos各版本安装指南

下载链接 https://pan.baidu.com/s/1L5qeUPMW32d7zR-GlVVZIw?pwd0531 温馨提示&#xff1a;若您下载的安装包与该安装步骤不同&#xff0c;说明您使用的是之前被淘汰的安装包&#xff0c;请通过该页面的下载链接重新下载。 1.鼠标右击【Rhino8.1(64bit)】压缩包&#xff08…

单挑力扣(LeetCode)SQL题:1951. 查询具有最多共同关注者的所有两两结对组(难度:中等)

题目&#xff1a;1951. 查询具有最多共同关注者的所有两两结对组 &#xff08;通过次数2,464 | 提交次数3,656&#xff0c;通过率67.40%&#xff09; 表: Relations ------------------- | Column Name | Type | ------------------- | user_id | int | | follower_id |…

电子握力器改造

toy_hand_game 介绍 消耗体力玩具&#xff0c;使用握力器(Grip Strengthener)控制舵机旋转。 开始设想是控制丝杆电机滑动&#xff0c;两套设备就可以控制两个丝杆电机进行“模拟拔河”&#xff0c;后续发现硬件设计错误&#xff0c;ULN2003不能控制两相四线电机&#xff0c;…

任务调度-hangfire

目录 一、Hangfire是什么&#xff1f; 二、配置服务 1.配置Hangfire服务 2.添加中间件 3.权限控制 三、配置后台任务 1.在后台中调用方法 2.调用延时方法 3.执行周期性任务 四、在客户端上配置任务 1.在AddHangfire添加UseHangfireHttpJob方法 2.创建周期任务 3.创建只读面板 总…

Oracle 12c rac 搭建 dg

环境 rac 环境 &#xff08;主&#xff09;byoradbrac 系统版本&#xff1a;Red Hat Enterprise Linux Server release 6.5 软件版本&#xff1a;Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit byoradb1&#xff1a;172.17.38.44 byoradb2&#xff1a;…