八大排序浅入浅出

news2024/11/26 16:27:16

1)选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;

2)按增量序列个数k,对序列进行k 趟排序;

3)每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

代码实现:

复制代码

#include<stdio.h>

#include<math.h> #define MAXNUM 10 void main() { void shellSort( int array[], int n, int t); // t为排序趟数 int array[MAXNUM],i; for(i = 0;i < MAXNUM;i++ ) scanf( " %d ",& array[i]); shellSort(array,MAXNUM, int(log(MAXNUM + 1) / log( 2))); // 排序趟数应为log2(n+1)的整数部分 for(i = 0;i < MAXNUM;i++ ) printf( " %d " ,array[i]); printf( " \n " ); } // 根据当前增量进行插入排序 void shellInsert( int array[], int n, int dk) { int i,j,temp; for(i = dk;i < n;i++) // 分别向每组的有序区域插入 { temp = array[i]; for(j = i-dk;(j >= i % dk) && array[j] > temp;j -= dk) // 比较与记录后移同时进行 array[j + dk] = array[j]; if(j != i - dk) array[j + dk] = temp; // 插入 } } // 计算Hibbard增量 int dkHibbard( int t, int k) { return int(pow( 2,t - k + 1) - 1 ); } // 希尔排序 void shellSort( int array[], int n, int t) { void shellInsert( int array[], int n, int dk); int i; for(i = 1;i <= t;i++ ) shellInsert(array,n,dkHibbard(t,i)); } // 此写法便于理解,实际应用时应将上述三个函数写成一个函数。

复制代码

算法三:选择排序


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

选择排序示意图

选择排序(Selection sort)也是一种简单直观的排序算法。

算法步骤

1)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置

2)再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

3)重复第二步,直到所有元素均排序完毕。

代码实现:

复制代码

void select_sort(int *a,int n)

{

register int i,j,min,t;

for(i = 0;i < n-1;i++)

{

min = i;//查找最小值

for(j = i + 1;j < n;j++)

if(a[min] > a[j])

min = j;//交换

if(min != i)

{

t = a[min];

a[min] = a[i];

a[i] = t;

}

}

}

复制代码

算法四:冒泡排序


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

冒泡排序示意图

冒泡排序Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

算法步骤

1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。

2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

3)针对所有的元素重复以上的步骤,除了最后一个。

4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

代码实现:

复制代码

#include <stdio.h>

#define SIZE 8void bubble_sort(int a[], int n)

{

int i, j, temp;

for (j = 0;j < n - 1;j++)

for (i = 0;i < n - 1 - j;i++)

{

if(a[i] > a[i + 1])

{

temp = a[i];

a[i] = a[i + 1];

a[i + 1] = temp;

}

}

}

int main()

{

int number[SIZE] = {95, 45, 15, 78, 84, 51, 24, 12};

int i;

bubble_sort(number, SIZE);

for (i = 0; i < SIZE; i++)

{

printf(“%d”, number[i]);

}

printf(“\n”);

}

复制代码

算法五:归并排序


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

归并排序示意图

**归并排序(Merge sort)**是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

算法步骤:

1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置

3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

4. 重复步骤3直到某一指针达到序列尾

5. 将另一序列剩下的所有元素直接复制到合并序列尾

代码实现:

复制代码

#include <stdlib.h>

#include <stdio.h> void Merge( int sourceArr[], int tempArr[], int startIndex, int midIndex, int endIndex) { int i = startIndex, j=midIndex+ 1, k = startIndex; while(i != midIndex + 1 && j != endIndex + 1 ) { if(sourceArr[i] >= sourceArr[j]) tempArr[k++] = sourceArr[j++ ]; else tempArr[k++] = sourceArr[i++ ]; } while(i != midIndex+ 1 ) tempArr[k++] = sourceArr[i++ ]; while(j != endIndex+ 1 ) tempArr[k++] = sourceArr[j++ ]; for(i = startIndex; i <= endIndex; i++ ) sourceArr[i] = tempArr[i]; } // 内部使用递归 void MergeSort( int sourceArr[], int tempArr[], int startIndex, int endIndex) { int midIndex; if(startIndex < endIndex) { midIndex = (startIndex + endIndex) / 2 ; MergeSort(sourceArr, tempArr, startIndex, midIndex); MergeSort(sourceArr, tempArr, midIndex+ 1 , endIndex); Merge(sourceArr, tempArr, startIndex, midIndex, endIndex); } } int main( int argc, char * argv[]) { int a[ 8] = { 50, 10, 20, 30, 70, 40, 80, 60 }; int i, b[ 8 ]; MergeSort(a, b, 0, 7 ); for(i= 0; i< 8; i++ ) printf( " %d " , a[i]); printf( " \n " ); return 0 ; }

复制代码

算法六:快速排序


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

快速排序示意图

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(_n_2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

算法步骤:

1 从数列中挑出一个元素,称为 “基准”(pivot),

2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为**分区(partition)**操作。

3 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

代码实现:

复制代码

void Qsort(int a[], int low, int high)

{

if(low >= high)

{

return;

}

int first = low;

int last = high;

int key = a[first];/*用字表的第一个记录作为枢轴*/

while(first < last)

{

while(first < last && a[last] >= key)

{

–last;

}

a[first] = a[last];/*将比第一个小的移到低端*/

while(first < last && a[first] <= key)

{

++first;

}

a[last] = a[first];

/*将比第一个大的移到高端*/

}

a[first] = key;/*枢轴记录到位*/

Qsort(a, low, first-1);

Qsort(a, first+1, high);

}

复制代码

算法七:堆排序


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

堆排序示意图

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足_堆积的性质_:即子结点的键值或索引总是小于(或者大于)它的父节点。

堆排序的平均时间复杂度为Ο(n_log_n) 。

算法步骤:

1)创建一个堆H[0…n-1]

2)把堆首(最大值)和堆尾互换

3)把堆的尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置

4) 重复步骤2,直到堆的尺寸为1

代码实现:

复制代码

//array是待调整的堆数组,i是待调整的数组元素的位置,nlength是数组的长度

//本函数功能是:根据数组array构建大根堆

void HeapAdjust(int array[],int i,int nLength)

{

int nChild;

int nTemp;

for(; 2 * i + 1 < nLength;i = nChild)

{

//子结点的位置=2*(父结点位置)+1

nChild = 2 * i + 1;

//得到子结点中较大的结点

if(nChild < nLength - 1 && array[nChild + 1] > array[nChild]) ++nChild;

//如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点

if(array[i] < array[nChild])

{

nTemp = array[i];

array[i] = array[nChild];

array[nChild] = nTemp;

}

else break; //否则退出循环

}

}

//堆排序算法

void HeapSort(int array[],int length)

{

int i;

//调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素

//length/2-1是最后一个非叶节点,此处"/"为整除

for(i = length / 2 - 1;i >= 0;–i)

HeapAdjust(array,i,length);

//从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素

for(i = length - 1;i > 0;–i)

{

//把第一个元素和当前的最后一个元素交换,

//保证当前的最后一个位置的元素都是在现在的这个序列之中最大的

array[i] = array[0] ^ array[i];

array[0] = array[0] ^ array[i];

array[i] = array[0] ^ array[i];

//不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值

HeapAdjust(array,0,i);

}

}

int main()

{

int i;

int num[]={9,8,7,6,5,4,3,2,1,0};

HeapSort(num,sizeof(num)/sizeof(int));

for(i = 0;i < sizeof(num) / sizeof(int);i++)

{

printf("%d ",num[i]);

}

printf(“\nok\n”);

return 0;

}

复制代码

算法八:基数排序


基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

说基数排序之前,我们简单介绍桶排序:

**算法思想:**是将阵列分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递回方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的阵列内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是 比较排序,他不受到 O(n log n) 下限的影响。

简单来说,就是把数据分组,放在一个个的桶中,然后对每个桶里面的在进行排序。

例如要对大小为[1…1000]范围内的n个整数A[1…n]排序

首先,可以把桶设为大小为10的范围,具体而言,设集合B[1]存储[1…10]的整数,集合B[2]存储   (10…20]的整数,……集合B[i]存储(   (i-1)*10,   i*10]的整数,i   =   1,2,…100。总共有  100个桶。

然后,对A[1…n]从头到尾扫描一遍,把每个A[i]放入对应的桶B[j]中。  再对这100个桶中每个桶里的数字排序,这时可用冒泡,选择,乃至快排,一般来说任  何排序法都可以。

最后,依次输出每个桶里面的数字,且每个桶中的数字从小到大输出,这  样就得到所有数字排好序的一个序列了。

假设有n个数字,有m个桶,如果数字是平均分布的,则每个桶里面平均有n/m个数字。如果

对每个桶中的数字采用快速排序,那么整个算法​
的复杂度是

O(n   +   m   *   n/m*log(n/m))   =   O(n   +   nlogn   –   nlogm)

从上式看出,当m接近n的时候,桶排序复杂度接近O(n)

当然,以上复杂度的计算是基于输入的n个数字是平均分布这个假设的。这个假设是很强的  ,实际应用中效果并没有这么好。如果所有的数字都落在同一个桶中,那就退化成一般的排序了。

前面说的几大排序算法 ,大部分时间复杂度都是O(n2),也有部分排序算法时间复杂度是O(nlogn)。而桶式排序却能实现O(n)的时间复杂度。但桶排序的缺点是:

1)首先是空间复杂度比较高,需要的额外开销大。排序有两个数组的空间开销,一个存放待排序数组,一个就是所谓的桶,比如待排序值是从0到m-1,那就需要m个桶,这个桶数组就要至少m个空间。

2)其次待排序的元素都要在一定的范围内等等。

代码实现:

复制代码

int maxbit(int data[], int n) //辅助函数,求数据的最大位数

{

int d = 1; //保存最大的位数

int p = 10;

for(int i = 0; i < n; ++i)

{

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取
空间复杂度比较高,需要的额外开销大。排序有两个数组的空间开销,一个存放待排序数组,一个就是所谓的桶,比如待排序值是从0到m-1,那就需要m个桶,这个桶数组就要至少m个空间。

2)其次待排序的元素都要在一定的范围内等等。

代码实现:

[外链图片转存中…(img-Ar3JvAPy-1719098290742)]

int maxbit(int data[], int n) //辅助函数,求数据的最大位数

{

int d = 1; //保存最大的位数

int p = 10;

for(int i = 0; i < n; ++i)

{

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

[外链图片转存中…(img-Ctaxle5o-1719098290743)]一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取

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

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

相关文章

头歌资源库(16)分苹果

一、 问题描述 二、算法思想 首先&#xff0c;我们可以初始化一个数组apple来记录每个孩子分配的苹果数量&#xff0c;将所有元素初始化为1&#xff0c;表示每个孩子至少分配到一个苹果。 然后&#xff0c;从左到右遍历评分数组ratings&#xff0c;判断当前孩子的评分与前一个…

自动驾驶仿真测试用例表格示例 ACC ELK FCW

自动驾驶仿真测试用例表格示例 测试用例概览 本测试用例表格涵盖了自动驾驶系统中多个关键功能和场景的测试&#xff0c;旨在确保系统在不同条件下的表现和稳定性。 用例编号测试项目测试描述预期结果实际结果通过/失败TC-001ACC功能测试在高速公路上启用ACC&#xff0c;测试车…

2024最新版Python 3.12.4安装使用指南

2024最新版Python 3.12.4安装使用指南 2024最新版Python 3.12.4安装使用指南0. Python的受欢迎程度1. 安装最新版Python 3.12.42. 验证Python 3.12.4版本3. 验证Python功能4. 使用IDLE交互式开发模式5. 安装Python扩展库相关阅读&#xff1a; By Jackson 2024最新版Python 3.12…

C语言笔试题:实现把一个无符号整型数字的二进制序列反序后输出

目录 题目 实例 方法一&#xff1a;直接交换 方法二&#xff1a;间接交换 拓展 题目 编写一个函数&#xff0c;将一个无符号整数的所有位逆序&#xff08;在32位机器下&#xff09; 实例 例如有一个无符号整数 unsigned int num 32; unsigned int 在32位系统中占4个字…

C# 中的静态关键字

C# 语言中的 static 关键字用于声明静态类和静态类成员。静态类和静态类成员&#xff08;如构造函数、字段、属性、方法和事件&#xff09;在只需要一个对象&#xff08;类或类成员&#xff09;副本并在类型&#xff08;和成员&#xff09;的所有实例&#xff08;对象&#xff…

基于SpringBoot+Vue汽车配件销售管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…

css-vxe列表中ant进度条与百分比

1.vxe列表 ant进度条 <vxe-column field"actualProgress" title"进度" align"center" width"200"><template #default"{ row }"><a-progress:percent"Math.floor(row.actualProgress)"size"s…

算法竞赛创新实践总结

目录 1 算法题目................................... 3 1.1 盛最多水的容器.......................... 3 1.1.1 题目................................ 3 1.1.2 双指针.............................. 4 1.1.3 代码................................ 5 1.2 分巧克力...…

【辨析】快速了解RBF神经网络与BP神经网络的区别

本文来自《老饼讲解-BP神经网络》https://www.bbbdata.com/ 目录 一、RBF与BP模型简介1.1.模型结构1.2.模型表达式 二、RBF神经网络与BP神经网络的对比2.1 RBF与BP的激活函数对比2.2 RBF与BP的思想对比 三、RBF神经网络与BP神经网络的训练方法对比2.1.BP神经网络的训练2.2.RBF神…

分布式架构的优势与实现

目录 前言1. 什么是分布式架构1.1 分布式架构的定义1.2 分布式架构的基本原理 2. 分布式架构的优势2.1 可扩展性2.2 容错性和高可用性2.3 性能优化2.4 灵活性和可维护性 3. 分布式架构的实现方法3.1 服务拆分3.1.1 功能拆分3.1.2 垂直拆分3.1.3 水平拆分 3.2 数据分布与存储3.2…

ES6 解构赋值详解

ES6是JavaScript语言的一次重大更新&#xff0c;引入了许多新特性和语法改进&#xff0c;其中解构赋值是一个非常实用和灵活的语法特性。它可以让我们从数组或对象中提取值&#xff0c;并赋给对应的变量&#xff0c;让代码变得更加简洁和易读。本文将深入探讨ES6解构赋值的语法…

Python | Leetcode Python题解之第179题最大数

题目&#xff1a; 题解&#xff1a; class Solution:def largestNumber(self, nums: List[int]) -> str:def quick_sort(l , r):if l > r: returni, j l, rwhile i < j:while strs[j] strs[l] > strs[l] strs[j] and i < j: j - 1while strs[i] strs[l] &l…

解决:Xshell通过SSH协议连接Ubuntu服务器报“服务器发送了一个意外的数据包,received:3,expected:20”

下图所示&#xff1a; 日志也基本看不出来问题在哪&#xff0c;只是说断开了连接大概是验证失败。有幸在某论坛评论区找到了原因&#xff0c;是因为我的xshell版本太低了而服务器的ssh版本太高&#xff0c;高版本的ssh默认屏蔽了一部分不太安全的算法导致建立连接的时候验证失败…

字节大牛耗时八个月又一力作,Android性能调优秘籍:设计思想与代码质量优化+程序性能优化+开发效率优化(全网疯传)

第一章、设计思想与代码质量优化 一、六大原则 二、设计模式 三、数据结构 四、算法 第二章、 程序性能优化 一、启动速度与执行效率优化 二、 布局检测与优化 三、 内存优化 四、耗电优化 五、网络传输与数据存储优化 六、APK 大小优化 第三章、 开发效率优化 一、…

【PL理论深化】(2) 语法分析 (Syntax) | 编程语言的语法结构:文法 | 语义结构 (Sematics)

&#x1f4ac; 写在前面&#xff1a;编程语言是由归纳法生成的程序的集合。定义属于该语言的程序的形式的规则&#xff0c;即编写程序的规则&#xff0c;称为编程语言的 语法分析 (syntax) 而定义属于该语言的程序的意义的规则称为 语义结构(semantics)。这两者都是归纳定义的。…

学习笔记——路由网络基础——路由转发

六、路由转发 1、最长匹配原则 最长匹配原则 是支持IP路由的设备默认的路由查找方式(事实上几乎所有支持IP路由的设备都是这种查找方式)。当路由器收到一个IP数据包时&#xff0c;会将数据包的目的IP地址与自己本地路由表中的表项进行逐位(Bit-By-Bit)的逐位查找&#xff0c;…

HCIP--OSPF(笔记3)

OSPF扩展配置 手工认证 【1】接口认证 -- 直连的邻居间&#xff0c;设定认证口令&#xff0c;进行身份核实&#xff0c;同时对双方交互的数据进行加密保护 [r9-GigabitEthernet0/0/1]ospf authentication-mode md5 1 cipher 123456 邻居间认证模式、编号、密码必须完全一致 【…

【UML用户指南】-20-对基本行为建模-交互图

目录 1、概述 2、顺序图 2.1、两个不同于通信图的特征&#xff1a; 2.1.1、顺序图有对象生命线 2.1.2、顺序图有控制焦点 2.2、结构化控制 2.2.1、可选执行opt 2.2.2、条件执行alt 2.2.3、并行执行par 2.2.4、循环迭代执行loop 2.3、嵌套活动图 3、通信图 3.1、两…

Selenium WebDriver - 网络元素

本文翻译整理自&#xff1a;https://www.selenium.dev/documentation/webdriver/elements/ 文章目录 一、文件上传二、定位策略1、传统定位器2、创建定位器3、类名4、CSS选择器5、id6、NAME7、链接文本8、部分链接文本9、标签名称10、xpath11、相对定位器它是如何工作的可用相对…

java中Object和json相互转换的方式

1.org中jackson转换json,springboot中内置jackson ObjectMapper onew ObjectMapper(); List<>listnew ArrayList(); String jonso.writeAsValueString(list); 2.alibaba中fastjson转换成json GetMapping("/test")public TbUser testHttpClient(){String url…