八大排序浅入浅出

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行业感兴趣的新人

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

资料⬅专栏获取

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FlinkCDC pipeline模式 mysql-to-paimon.yaml

flinkcdc 需要引入&#xff1a; source端&#xff1a; flink-cdc-pipeline-connector-mysql-xxx.jar、mysql-connector-java-xxx.jar、 sink端&#xff1a; flink-cdc-pipeline-connector-paimon-xxx.jar flinkcdc官方提供connect包下载地址&#xff0c;pipeline模式提交作业和…

Linux查看公网IP的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

STM32单片机BKP备份寄存器和RTC实时时钟详解

文章目录 1. Unix时间戳 2. UTC/GMT 3. 时间戳转换 4. BKP简介 5. BKP基本结构 6. RTC简介 7. RTC框架图 8. RTC基本结构 9. 代码示例 1. Unix时间戳 实时时钟&#xff0c;本质上是一个定时器&#xff0c;专门用来产生年月日时分秒。 Unix 时间戳&#xff08;Unix T…

Apple - Cocoa Event Handling Guide

本文翻译整理自&#xff1a;Cocoa Event Handling Guide&#xff08; https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/Introduction/Introduction.html#//apple_ref/doc/uid/10000060i 文章目录 一、导言本文件的组织另见 二、事件…

如何通过防泄密U盘,实现数据传输的安全性及可控性?

随着信息技术的发展&#xff0c;U盘作为重要的数据存储和传输工具&#xff0c;其安全性越来越受到关注。在日常办公中&#xff0c;经常会遇到这类情况&#xff1a;员工为了方便&#xff0c;随意使用U盘拷贝公司的机密资料。一旦U盘丢失或者被窃取&#xff0c;公司的机密资料就有…

Part 8.2 最短路问题

很多题目都可以转化为最短路的模型。因此&#xff0c;掌握最短路算法非常重要。 >最短路模板< 【模板】全源最短路&#xff08;Johnson&#xff09; 题目描述 给定一个包含 n n n 个结点和 m m m 条带权边的有向图&#xff0c;求所有点对间的最短路径长度&#xff…

vue-Router实现原理

http://localhost:8080/home 三、HashHistory hash("#")的作用是加载 URL 中指示网页中的位置。# 号后面的 hash值&#xff0c;可通过 window.location.hash 获取 特点&#xff1a; hash 不会被包括在 http 请求中&#xff0c;&#xff0c;对服务器端完全无用&…

《黑悟空》抢先版

当《西游记》的古老传说与现代潮流碰撞&#xff0c;一个全新的西游世界在《黑神话悟空》中缓缓展开。你&#xff0c;作为被选中的“天命人”&#xff0c;将踏上一段寻找真相的奇幻旅程。在这里&#xff0c;中国神话的深邃与东方魔幻的绚丽交织&#xff0c;构建出一个令人叹为观…

VBA技术资料MF165:关闭当前打开的所有工作簿

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

Origin较好用的科研绘图软件

推荐自己也在用的科研绘图软件Origin图所示&#xff1a; 图1 图2 图3

Android 装逼技术之暗码启动应用

AdapterView.OnItemClickListener, TextWatcher, PopupMenu.OnMenuItemClickListener, DialpadKeyButton.OnPressedListener { //…… Override public void afterTextChanged(Editable input) { // When DTMF dialpad buttons are being pressed, we delay SpecialChar…

FPGA国内”薪“赛道-在医疗领域的应用

mian 免 ze 责 sheng 声 ming 明 以下观点仅代表个人观点&#xff0c;不代表任何公司或者行业 从下游应用市场来看&#xff0c;通信和工业市场份额位居FPGA芯片一二位&#xff0c;同时通信市场份额有望持续提升。但是目前通信和工业市场趋于稳定&#xff0c;FPGA厂商一直推AI市…

408计算机组成原理

todo:有逻辑的分门别类的整理笔记&#xff0c;方便复习 总 理解不了就直接背下来&#xff0c;学越多就越能理解 计算机系统概述 简要目录 基本概念 字长 MAR MDR PC IR CU ALU 通用寄存器、标志寄存器、标志控制器 ACC 地址译码器 通用寄存器 PU C语言编译过程 数据通路带…

FlinkCDC sink paimon 暂不支持exactly-once写入,而通过 幂等写

幂等写入&#xff1a; 一个幂等操作无论执行多少次都会返回同样的结果。例如&#xff0c;重复的向hashmap中插入同样的key-value对就是幂等操作&#xff0c;因为头一次插入操作之后所有的插入操作都不会改变这个hashmap&#xff0c;因为hashmap已经包含这个key-value对了。另一…

基于matlab的BP神经网络分类预测

1.神经网络结构 本文网络结构如图1所示&#xff1a; 图1 网络结构 图1给出的并不是单纯的bp神经网络结构这里设置了三个隐藏层&#xff0c;神经元个数分别为6&#xff0c;3&#xff0c;3&#xff0c;输入层12个特征输入&#xff0c;输出层输出4个类型结果。 2.代码 %% 清空环…

自动驾驶仿真Carla -ACC功能测试

我将详细说明如何使用Carla进行ACC&#xff08;自适应巡航控制&#xff09;测试&#xff0c;确保每个步骤贴合实际的Carla自动驾驶仿真标准&#xff0c;并提供相应的代码示例。 使用Carla进行ACC测试的步骤&#xff1a; 1. 环境设置和启动Carla 首先&#xff0c;确保你已经安装…

bug记录——C语言中运算符前假后面不执行

A&&B A为真&#xff0c;才会判断B&#xff0c; 所以如果B访问越界的情况下必有A为假&#xff0c;那么代码是正确的 像这里&#xff0c;当child 1 > n时&#xff0c;a[child 1]越界访问&#xff0c; 但由于&&前面判断了child 1 < n为假&#xff0c;所以…

element-ui里message抖动问题

由于element默认屏蔽滚动条&#xff0c;导致取消时弹message时 侧边滚动栏突然回来后引起抖动问题 是由于打开弹窗时出现遮罩层dialog对话框 时引起了元素内容超出自身尺寸 对应的overflow样式内容为hidden&#xff0c;且新建了一个class类内容为增加17 内右边距&#xff0c;当…

QML 实现上浮后消失的提示框

基本效果&#xff1a;上浮逐渐显示&#xff0c;短暂停留后上浮逐渐消失 为了能同时显示多个提示框&#xff0c;一是需要动态创建每个弹框 Item&#xff0c;二是弹出位置问题&#xff0c;如果是底部为基准位置就把已经弹出的往上移动。 效果展示&#xff1a; 主要实现代码&…