排序(插入,希尔,堆排,冒泡)

news/2024/9/28 11:52:55/

常见的算法>排序算法
在这里插入图片描述

插入排序:
直接插入排序:是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。保证插入之前的数组是有序的,插入后也保证是有序的。时间复杂度:原数组如果和需要排的顺序逆序的时候是最坏的情况,O(N^2),和冒泡排序时间复杂度相同。最好的情况是O(N),顺序有序。

// 直接插入插入排序
void InsertSort(int* a, int n)
{//多趟排序for(int i = 0; i < n-1; ++i) // 当n = n-2时,插入的就是第n-1的位置的值,就完成了n个数的插入。{// 单趟排序 把tmp插入数组[0,end]的有序区间int end = i; // 从后往前判断,end 就是当前判断的最后一个值int tmp = a[end + 1]; // end外面要插入的数据while(end >= 0) // 从后往前,end--{if(tmp < a[end]){a[end + 1] = a[end]; //让end位置的值放在end+1的位置end--; }elsebreak; // 说明tmp >= a[end-1]}a[end + 1] = tmp; // 需要在end-1的后面 也就是end+1的位置存放tmp}
} 

希尔排序:再插入排序的基础上,让数组首先接近于有序。也就是1.预排序 ->让数组接近有序,2.直接插入排序。
预排序 ->先分组,对分组的数据进行插入排序。间隔为gap的分成一组,对一组进行插入排序。
蓝色的整体为一组,红色的整体为一组,绿色的整体为一组。每次比较的时候只比较各自颜色指向的数字,以蓝色为例,也就是9,5,8,5相比较后进行排序。
gap越大,说明大的数和小的数可以更快的挪到对应的位置,但gap越大越不接近有序。gap越小则相反。
如果gap==1,则就是直接插入排序。排序的规则就是gap = 5, gap = 3, gap = 1来三次就完成希尔排序。
希尔排序的时间复杂度不好计算,需要进行推导,推导出来平均时间复杂度: O(N^1.3- N^2)
在这里插入图片描述

 // 希尔排序
void ShellSort(int* a, int n)
{int gap = n;// 整个循环最坏是O(N*log3(N))while(gap > 1) // n/3/3/3/3/../3 = 1截至 -> 3^x = n, x = log3(N)就是while的次数{gap = (gap / 3 + 1); //这样可以保证gap最后一次是1。// i<n-gap 则对应上图的话就到蓝色8这个位置,i一直加到这个位置可以把蓝色红色和绿色全部处理完。// 也就是 先蓝色,再红色,再绿色,再蓝色,再红色,再绿色,再蓝色(8这个位置)就完了。因为后面红色绿色只有一个数。// gap很大时是预排序让它接近有序,就是O(N)。// gap很小时,本应该是O(N*N),但是经过了预排序,数组很接近有序,所以也接近于O(N)// 因此,这个for循环就是O(N)for(int i = 0; i < n-gap; ++i) {int end = i;int tmp = a[end + gap]; //要插入的值while(end >= 0) // 间隔为gap的排序,类似于直接插入排序(间隔为1){if(tmp < a[end]){a[end + gap] = a[end];end -= gap;}elsebreak;}a[end + gap] = tmp;}}
}

直接选择排序:在数组中直接选择最大的,次大的放到相应位置直接排。

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}
// 选择排序 O(N^2) 无论如何都会遍历一遍选择数
void SelectSort(int* a, int n)
{// 将最小的放在最左边,最大的放在最右边,让左右位置往中间夹int left = 0;int right = n-1;while(left < right){int minIndex = left, maxIndex = left;for(int i=left; i<right; ++i){if(a[i] < a[minIndex]) // 选出最小的minIndex = i;if(a[i] > a[maxIndex]) //选出最大的maxIndex = i;}Swap(&a[left], &a[minIndex]); //如果最大值在left位置,上面交换后max就被换走了 换到minIndex的位置去了 修正位置。if(left == maxIndex) {maxIndex = minIndex;}Swap(&a[right], &a[maxIndex]);++left;--right;}
}

堆排序:先得有个堆然后再选择出放到特定位置的选择排序方法。
堆排序的详细介绍

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}// 堆排序 建堆是O(N) 每次调整需要O(logN)(调整一次走高度次,高度是logN) 因此堆排序是O(NlogN)//自顶向下的调整,但是parent的传参是自下而上的传,先保证最下面的parent及其子节点属于大堆,再一层一层的向上传parent。
void AdjustDwon(int* a, int n, int parent)
{int child = parent*2 + 1;while(child < n){// 建大堆 选出左右孩子大的if(child + 1 < n && a[child + 1] > a[child]){child++;}if(a[parent] < a[child]){Swap(&a[parent], &a[child]);parent = child;child = parent*2 + 1;}elsebreak;}
}
void HeapSort(int* a, int n)
{// 建堆 parent的传参是自下而上的传,先保证最下面的parent及其子节点属于大堆,再一层一层的向上传parent。for(int i = (n-1-1)/2; i >=0; --i){AdjustDwon(a, n, i);}int end = n-1;while(end > 0) //只剩一个数就不选了{Swap(&a[0], &a[end]);// 再选出次大的 因为之前已经建堆完成了,因此只有换上去到最上面的那个数不满足大堆的排序,把它排好就行AdjustDwon(a, end, 0)end--; //每次最后一个位置就是被调换过的最大的、次大的...的数}
}

冒泡排序:定义两个指针,指向第一个和第二个位置,前一个比后一个大就交换,然后同时向后挪接着比较,把最大的放到最后一个位置。最坏的情况:O(N^2),最好的情况:O(N)。冒泡和插入的时间复杂度差不多相同,但是当数组接近有序时,她两比起来插入好一些。
在这里插入图片描述

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}
// 冒泡排序
void BubbleSort(int* a, int n)
{for(int end = n; end > 0; end--){int exchange = 0;for(int i = 1; i<end; i++){if(a[i-1] < a[i]){Swap(&a[i-1], &a[i]);exchange = 1;}}if(exchange == 0) //如果没有发生交换,可以提前结束程序break;}
}

http://www.ppmy.cn/news/1531510.html

相关文章

2024AI做PPT软件如何重塑演示文稿的创作

现在AI技术的发展已经可以帮我们写作、绘画&#xff0c;最近我发现了不少ai做ppt的工具&#xff01;不体验不知道&#xff0c;原来合理使用AI工具可以有效的帮我们进行一些办公文件的编写&#xff0c;提高了不少工作效率。如果你也有这方面的需求就接着往下看吧。 1.笔灵AIPPT…

PHP爬虫:获取商品SKU详细信息的艺术

在电子商务的世界里&#xff0c;SKU&#xff08;Stock Keeping Unit&#xff0c;库存单位&#xff09;是每个商品的唯一标识符&#xff0c;它包含了商品的详细信息&#xff0c;如尺寸、颜色、价格等。对于商家和开发者来说&#xff0c;获取商品的SKU详细信息对于库存管理、订单…

oracle 如何判断当前时间在27号到当月月底

在Oracle中&#xff0c;您可以使用TRUNC和LAST_DAY函数来判断当前时间是否在27号到当月月底之间。以下是一个SQL示例&#xff1a; SELECT CASE WHEN TRUNC(SYSDATE) > TRUNC(SYSDATE, DD) 26 AND TRUNC(SYSDATE) < LAST_DAY(SYSDATE) THEN 当前时间在27号到当月月底之间…

老男孩教育trabackup全量和增量恢复案例-xbk备份

xtrabackup全量和增量备份 中小企业MySQL Xtrabackup物理增量恢复案例实战 如果对运维课程感兴趣,可以在b站上、csdn或微信视频号 上搜索我的账号: 运维实战课程,可以关注我,学习更多免费的运维实战技术视频 1.安装mariadb-mysql5.5 (xbk备份也适用于mysql5.7.x,只是…

vue仿chatGpt的AI聊天功能--大模型通义千问(阿里云)

vue仿chatGpt的AI聊天功能–大模型通义千问&#xff08;阿里云&#xff09; 通义千问是由阿里云自主研发的大语言模型&#xff0c;用于理解和分析用户输入的自然语言。 1. 创建API-KEY并配置环境变量 打开通义千问网站进行登录&#xff0c;登陆之后创建api-key&#xff0c;右…

一天认识一个硬件之机箱

台式机除了里面的配件外&#xff0c;还需要机箱来安装这些配件&#xff0c;不同的机箱之间&#xff0c;适配不同的作用 今天就来分享一下台式机的机箱及特点 1ITX机箱&#xff1a; 特点&#xff1a;体积小巧&#xff0c;设计紧凑&#xff0c;便于携带。适合空间有限或追求便…

haproxy程序崩溃问题处理

背景&#xff1a; 线上一k8s环境告警出节点失联&#xff0c;通过排查和k8s的api建立链接失败&#xff0c;检查发现haproxy出现了重启&#xff0c;对应的日志显示出程序运行崩溃&#xff0c;这个情况根据日志追溯&#xff0c;发现曾多次崩溃&#xff0c;后续也在其他k8s环境也有…

搜维尔科技:使用Xsens动作捕捉系统和ai训练人形机器人模仿人类运动,执行复杂任务

人形机器人市场正在快速扩张:人形机器人市场将在未来大幅增长&#xff0c;据统计数据推算该市场将从2023年的13.2亿美元增长到2035年的约380亿美元&#xff0c;这显示出人形机器人市场强劲的增长趋势。 搜维尔科技&#xff1a;使用Xsens动作捕捉系统和ai训练人形机器人模仿人类…