C语言排序算法实现

news2024/10/3 20:28:39

1.概述

  所谓排序, 就是使一串记录, 按照其中的某个或某些关键字的大小, 递增或递减的排列起来的操作。 排序算法, 就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视, 尤其是在大量数据的处理方面。 一个优秀的算法可以节省大量的资源。 在各个领域中考虑到数据的各种限制和规范,要得到一个符合实际的优秀算法, 得经过大量的推理和分析。
  排序算法稳定性: 假定在待排序的记录序列中, 具有多个相同的元素, 若经过排序, 这些记录的相对次序保持不变, 即在原序列中, r[i]=r[j], 且 r[i]在 r[j]之前, 而在排序后的序列中, r[i]仍在 r[j]之前, 则称这种排序算法是稳定的; 否则称为不稳定的。
  时间复杂度: 即从序列的初始状态到经过排序算法的位置交换处理, 得到最终排序好的结果状态的过程所花费的时间度量。 在计算机科学中, 时间复杂性, 又称时间复杂度, 算法的时间复杂度是一个函数, 它定性描述该算法的运行时间。 这是一个代表算法输入值的字符串的长度的函数。 时间复杂度常用O符号表示。

2.冒泡排序

  冒泡排序实现原理是把较小元素(较大元素)往后调。通过对相邻元素进行两两比较,根据比较结果将两元素位置对调, 最终达到从小到大或者从大到小的顺序。
  冒泡排序的基本思想是: 如按从大到小顺序排序, 将第 1 个元素和第 2 个元素比较,若第 1 个小于第 2 个,则将两个元素位置交换, 反之则不动; 接着再对第 2 个元素和第 3 个元素比较, 若第 2 个小于第 3 个, 则将两个元素位置交换, 反之则不动; 依次类推, 一轮下来则将找到一个最小值放到最末尾。接下来在进行第二轮比较, 则可以找到第二小值放到倒数第二位置, 直到进行 n-1轮比较,即可使数据有序。
  冒泡排序时间复杂度: O(n²)
  冒泡排序是一个稳定的排序算法。
在这里插入图片描述

#include <stdio.h>
int main()
{	
	int data[]={4,1,3,6,2,5};
	int i=0,j;
	int temp;
	int count=sizeof(data)/sizeof(int);
	for(i=0;i<count-1;i++)//比较轮数
	{
		for(j=0;j<count-1-i;j++)//每轮比较的次数
		{
			if(data[j]>data[j+1])
			{
				temp=data[j];
				data[j]=data[j+1];
				data[j+1]=temp;
			}
		}
	}
	printf("从小到大:");
	for(i=0;i<count;i++)
	{
		printf("%d ",data[i]);
	}
	printf("\n");
}

2.快速排序

  快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
  (1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
  (2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于或等于分界值。
  (3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
  (4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
  快速排序(Quick_sort)是对冒泡排序的一种改进,它也是属于冒泡类的方法。
  快速排序时间复杂度:O(log2n)
  快速排序是一个不稳定的排序算法。
在这里插入图片描述

#include <stdio.h>
void quicksort(int *arr,int first,int end);
int main()
{
	int arr[]={3,5,7,1,2,4,6};
	quicksort(arr,0,7-1);
	int i=0;
	for(i=0;i<7;i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
	return 0;
}
void quicksort(int *arr,int first,int end)
{
	if(first>=end)return ;
	int i=first;
	int j=end;
	int pivot=arr[i];
	int cnt=0;
	while(1)
	{
		while(arr[i]<=pivot && i<end)i++;//从前往后找大于pivot的数
		while(arr[j]>=pivot && j>first)j--;//从后往前找小于pivot的数据
		if(i>=j)break;
		//交换位置
		int temp=arr[i];
		arr[i]=arr[j];
		arr[j]=temp;
	}
	arr[first]=arr[j];
	arr[j]=pivot;
	quicksort(arr,0,j);//对前半部分排序
	quicksort(arr,j+1,end);//对后半部分排序
}

3.插入排序

  插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的实现原理是将一个元素插入到一个有序列表中。其实现过程可以通过两层循环,外层循环控制有序列表的数量,内层循环是判断新元素,将新元素插入到有序列表中。

  • 时间复杂度:

  在插入排序中,当待排序数组是有序时,此时为最优情况,只需当前数跟前一个数比较一下,这时一共需要比较N- 1次,时间复杂度为O(N)
  最坏的情况是待排序数组是逆序的,此时需要比较次数最多,总次数记为:1+2+3+…+N-1,所以,插入排序最坏情况下的时间复杂度为O(N²)
  插入排序适用于已经有部分数据有序,并且有序数列越大越好。一般在数据规模大于1000的场合下不建议使用插入排序
  插入排序是一个不稳定的排序算法。
在这里插入图片描述

#include <stdio.h>
int main()
{
	char buff[]={3,5,7,1,2,64,6};
	int count=sizeof(buff)/sizeof(char);
	int i,j;
	int temp;
	for(i=1;i<count;i++)
	{
		for(j=i;j>0;j--)
		{
			if(buff[j]>buff[j-1])
			{
				temp=buff[j];
				buff[j]=buff[j-1];
				buff[j-1]=temp;
			}
		}
	}
	for(i=0;i<count;i++)
	{
		printf("%d ",buff[i]);
	}
	printf("\n");
}

4.希尔排序

  希尔排序(Shell’s Sort)是插入排序的一种,又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。该方法因 D.L.Shell于1959年提出而得名。
  希尔排序是把要排序的元素进行分组插入排序,把元素的分组数作为循环轮数,分组数量一般设置为log2N(N为成员个数)。每完成一轮,分组数量减半,直到组数为1,即整个元素分成一组,即排序完成。
  希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比O(N²)好一些。
  希尔排序是一个稳定的排序算法。
在这里插入图片描述

#include <stdio.h>
void shellSort(int *arr,int count)
{
	int gap=0;
	int temp;
	int i=0,j=0;
	for(gap=count>>1;gap>0;gap>>=1)
	{
		for(i=gap;i<count;i++)
		{
			temp=arr[i];
			j=i-gap;
			while(j>=0 && arr[j]<temp)
			{
				arr[j+gap]=arr[j];
				j-=gap;
			}
			arr[j+gap]=temp;
		}
	}
}
int main()
{
	int arr[]={1,2,3,4,5,6,7,8};
	int count=sizeof(arr)/sizeof(int);
	shellSort(arr,count);
	printf("从大到小排序:\n");
	for(int i=0;i<count;i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
}

5.选择排序

  选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。
  选择排序时间复杂度都是O(n²)
  选择排序是一个不稳定的排序算法。
在这里插入图片描述

void SelectSort(int *arr,int count)
{
	int i,j;
	int temp;
	int min;
	for(i=0;i<count-1;i++)
	{
		min=i;
		for(j=i+1;j<count;j++)
		{
			//找到最小的下下标
			if(arr[j]<arr[min])min=j;
		}
		temp=arr[i];
		arr[i]=arr[min];
		arr[min]=temp;
	}
}
void main(){
	int arr[] = {6,4,8,9,2,3,1,0};
	int count=sizeof(arr)/sizeof(int);
	SelectSort(arr,count);
	int i=0;
	printf("排序结果:");
	for(i=0;i<count;i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
}

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

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

相关文章

数据分析回头看1——Pandas中数据处理总结

0、前言&#xff1a;因为之前自己在学习pandas的过程中就简单做了下笔记&#xff0c;发现在用的时候还是会比较乏力&#xff0c;很多东西容易忘&#xff0c;所以我就决定结合之前笔记的内容&#xff0c;按照使用pandas的习惯&#xff0c;把知识点梳理一下&#xff0c;方便之后查…

网段扫描攻击

攻击简介 如果网络中有用户向设备发送大量目标IP地址不能解析的IP报文&#xff08;即路由表中存在该IP报文的目的IP对应的路由表项&#xff0c;但设备上没有该路由表项中下一跳对应的ARP表项&#xff09;&#xff0c;将导致设备触发大量的ARP Miss消息。 大量的网段扫描报文会…

软件测试的自我学习和提升

软件测试是一项非常重要的工作&#xff0c;它可以确保软件在发布前能够正常运行&#xff0c;在软件开发过程中扮演着至关重要的角色。在这个不断变化和创新的时代&#xff0c;软件测试人员需要不断地学习和提升自己的技能和能力&#xff0c;以适应不同软件发展的需求。 1. 学习…

LeetCode刷题 | 309. 最佳买卖股票时机含冷冻期、714. 买卖股票的最佳时机含手续费

309. 最佳买卖股票时机含冷冻期 给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09;: 卖出股票后&…

【MySQL学习笔记】(四)MySQL数据类型

MySQL数据类型 1 数据类型分类2 数值类型2.1 tinyint 类型2.2 bit 类型2.3 小数类型2.4 字符串类型2.5 varchar2.6 char和varchar比较 2.6 日期和时间类型2.6 enum 和 set2.6.1 集合查询使用find_ in_ set函数 1 数据类型分类 2 数值类型 2.1 tinyint 类型 数值测试 mysql>…

基于IP 的 Nginx 虚拟主机

目录 一、配置文件&#xff08;不要忘了备份&#xff09; 二、 访问地址 一、配置文件&#xff08;不要忘了备份&#xff09; 二、 访问地址

while(1) 和 for ( ; ; )的区别

while(1) 和 for(;;) 它们不都是无限循环吗&#xff0c;作用应该一样啊&#xff0c;它们到底有什么区别&#xff1f; 要回答这个问题&#xff0c;其实你各自编写一段while(1) 和 for(;;)的代码&#xff0c;编译对比一下代码大小和汇编文件&#xff0c;你就大概知道了。 while(…

Vue.extend

Vue.extend 方法用来对基本的Vue组件进行扩展&#xff0c;&#xff0c;创建他的子类&#xff0c;&#xff0c;通过扩展根节点Vue定义新的组件 const BaseComponent Vue.extend({data(){return{message:"hehe"}}})const ExtendedComponent BaseComponent.extend({mo…

5、Redis持久化

RDB&#xff08;默认&#xff09; 在指定的时间间隔&#xff0c;执行数据集的时间点快照 在指定的时间间隔&#xff0c;执行数据集的时间点快照 实现类似照片记录效果的方式&#xff0c;就是把某一时刻的数据和状态以文件的形式写到磁盘上&#xff0c;也就是快照。这样一来即使…

Mars3d实现对图层树顺序进行了调整的同时调整图层的层级

问题&#xff1a; 1.这个图层管理中的移动图层只是移动在树里的显示关系&#xff0c;数据的叠加优先级没有同步修改 原因&#xff1a; 1. 只对同类型图层才有效&#xff0c;如果是矢量图层需要zIndex的才有效。 比如&#xff1a;都是 geoserver发布的wms图层&#xff0c;这种…

六月喜报 | 震坤行荣获多项行业大奖!

六月喜报 | 震坤行荣获多项行业大奖&#xff01; 六月&#xff0c;震坤行先后荣获上海市工商联工业品服务商会行业五大奖项&#xff0c;以及SiMPL2023第十三届供应链年度中国供应链数字化创新先锋。一路荣誉加冕&#xff0c;蓄势前行&#xff0c;揽获多个行业奖项。 6月1日&am…

局域网远程连接

一根网线连接两台电脑 前言步骤1 设置B“允许远程连接”2 A和B必须在同一个网段下面3 “winr”&#xff0c;输入“mstsc”中4 弹出“远程桌面连接”窗口&#xff0c;输入B的ip地址和B电脑的用户名及密码&#xff08;winL键锁屏&#xff0c;看看B的用户名和密码是什么&#xff0…

python学习——函数

一、函数的定义 函数就是执行特定任务和完成特定功能的一段代码。使用函数可以对代码进行复用&#xff0c;提高代码的可维护性和可读性&#xff0c;使得程序便于调试。 二、函数的创建 创建格式 #创建和格式 def 函数名&#xff08;[参数]&#xff09;:函数体[return xxx]举例…

h5实现下拉选择

一、先看效果图 二、简单实现一下代码 首先你要引入jQuery.js文件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name…

Vue基础 el挂载点、data数据对象

第一步导入vue&#xff0c;第二步在html里面写一点东西&#xff0c;第三步在js里面写一点东西。 <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>首页</title><link href"" type"text/css"…

开发小程序为什么会成为餐饮行业的新趋势

在过去的一段时间里&#xff0c;小程序的发展可谓是如火如荼。特别是在餐饮行业&#xff0c;无论是大型连锁企业还是小型独立店铺&#xff0c;都在积极布局小程序开发&#xff0c;这一现象引发了我们的思考&#xff1a;为何开发小程序会成为餐饮行业的新趋势呢&#xff1f; 首…

d3dcompiler_47.dll缺失怎么修复,三种修复方法分享

打开游戏的时候&#xff0c;电脑报错“找不到d3dcompiler_47.dll无法继续执行此代码”&#xff0c;不知道怎么处理&#xff1f;下面小编就详细分享关于d3dcompiler_47.dll的三种修复方法以及作用。d3dcompiler_47.dll是Microsoft公司开发的动态链接库文件&#xff0c;属于Micro…

html实现好看的多种风格导航菜单(附源码)

文章目录 1.设计来源1.1 顶部导航菜单1.1.1 界面风格1-一二级连体导航菜单1.1.2 界面风格2-二级导航下拉框1.1.3 界面风格3-系统开始风格1.1.4 界面风格4-购物类导航菜单1.1.5 界面风格5 - 带搜索扩展的导航条1.1.6 界面风格6-火热效果多级导航条 1.2 悬浮按钮菜单1.2.1 界面风…

Retrofit学习基础

1. 基本使用 Retrofit 网络请求的工作本质上是OkHttp完成&#xff0c;而 Retrofit 仅负责 网络请求接口的封装。App应用程序通过Retrofit请求网络&#xff0c;实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息&#xff0c;之后由 OkHttp 完成后续的请求操作在服…

如何扫码看文件?多个文件如何独立建码?

现在用二维码来承载文件是很常见的一种方式&#xff0c;可以将多个不同文件做成一个二维码或者多个二维码&#xff0c;来让其他人扫码查看&#xff0c;那么文件转二维码的方法是如何来操作的呢&#xff1f;下面教大家使用二维码生成器&#xff08;免费在线二维码生成器-二维码在…