排序方法(冒泡、选择、插入、快速、希尔、桶排序、归并)

本文深入讲解了冒泡排序、选择排序、插入排序、快速排序、希尔排序、桶排序及归并排序等经典排序算法的原理与实现代码。通过实例演示,帮助读者理解不同排序算法的特点与适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、冒泡排序
冒泡排序:数列中两两比较,较大数往后移位

void fun1(int arr[],int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		for (int j = 0; j < n - i - 1; j++)
		{
			if (arr[j]>arr[j + 1])//相邻两个数进行比较,较大的一个往后移位
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}

二、选择排序
选择排序:每一轮找出最小的数出来,将其放置前位,一直到结束

void fun2(int arr[], int n)
{
	for (int i = 0; i < n-1; i++)
	{
		int temp = i;//将下标为i的元素暂时标记为最小值
		for (int j = i + 1; j < n; j++)
		{
			if (arr[j] < arr[temp])
			{
				temp = j;//与后比较,如果比原标记更小,标记更新
			}
		}
		int m = arr[temp];//将最小值前置
		arr[temp] = arr[i];
		arr[i] = m;
	}
}

三、插入排序
插入排序:将数列中的某元素插入至有序数列中,直至前元素比某元素小,从而位置定

 void fun3(int arr[], int n)
    {
    	for (int i = 1; i < n; i++)
    	{
    		int temp = arr[i],j=i-1;//temp标记需要插入元素
    		for (j; j >= 0; j--)
    		{
    			if (arr[j]>temp)//将前元素与标记元素比较,如果前元素比标记元素大,则前元素往后移位
    			{
    				arr[j + 1] = arr[j];
    			}
    			else break;//如果前元素比标记元素小,则跳出
    		}
    		arr[j + 1] = temp;
    	}
    }

四、快速排序
快速排序:
1 左边找比首元素大的,右边找比首元素小的
2 交换位置
3 将首元素放置至中心,作为中心轴
4 中心轴前面的元素从步骤1再次开始查找
5 中心轴后面的元素也从步骤1再次开始查找

void fun4(int arr[], int left, int right)
{
	if (left >= right)return 0;//如果元素只有一个或者左针移位到右针右边,则结束
	int i = left, j = right, temp;
	while (i < j)
	{
		while (i < j&&arr[left] < arr[j])//从右边开始查找比首元素小的
			j--;
		while (i < j&&arr[left] >= arr[i])//从左边开始查找比首元素大的
			i++;
		if (i < j)
		{
			temp = arr[j];//如果 一左一右,则交换位置
			arr[j] = arr[i];
			arr[i] = temp;
		}
	}
	temp = arr[left];//将首元素放置在中心位置
	arr[left] = arr[i];
	arr[i] = temp;
	fun4(arr, left, i - 1);//中心轴左边的元素递归进行上述查找
	fun4(arr, j + 1, right);//中心轴右边的元素递归进行上述查找
}

五、希尔排序
希尔排序是对插入排序的优化
排序规则:
1、首先初始化数组,假设数组的元素个数为10;
在这里插入图片描述
2、将数组分为N\2个子数组,即10/2=5个子数组
在这里插入图片描述
将数组分为5个子数组,(6,7)、(8,5)、(1,10)、(2,9)、(4,3)
对每个子数组使用插入排序进行排序,变成(6,7)、(5,8)、(1,10)、(2,9)、(3,4)
在这里插入图片描述
3、将数组分为N\2个子数组,即5/2=2个子数组
在这里插入图片描述
将数组分为2个子数组,(6,1,3,8,9)、(5,2,7,10,4)
对每个子数组使用插入排序进行排序,变成(1,3,6,8,9)、(2,4,5,7,10)
在这里插入图片描述
4、将数组分为N\2个子数组,即2/2=1个子数组
对子数组使用插入排序进行排序

在这里插入图片描述
具体实现代码:

#include<iostream>
using std::cin;
using std::endl;
using std::cout;
void shell_sort(int arr[],int len)
{
int j;
int tempVal;
int jump=len>>1;//N/2
while(jump>0)
{
for(int i=jump;i<len;++i)
{
tempVal=arr[i];
for(j=i-jump;j>=0&&tempVal<arr[j];j-=jump)
{
arr[j+jump]=arr[j];
}
arr[j+jump]=tempVal;
}
jump>>=1;
}
}
int main()
{
int arr[10]={6,8,1,2,4,7,5,10,9,3};
shell_sort(arr,10);
for(int i=0;i<10;++i)
{
cout<<arr[i]<<" ";
}
cout<<endl;
cin.get();
return 0;
}

六、桶排序
桶排序:将一系列元素放入定义好的数组中,在数组中就将顺序排列好,桶元素只针对于整数排序
用空间来换取效率的一种排序规则
代码实现:

 #include<iostream>
    using std::cin;
    using std::endl;
    using std::cout;
    #define N 11
  
    void bucket_sort(int arr[], int len)
{
 int temp[10][N] = { };
 int tempIndex;
 for (int n = 1; n < 1000; n *= 10)
 {
  for (int x = 0; x < 10; ++x)
  {
   for (int y = 0; y < N; ++y)
   {
    temp[x][y] = -1;//给二维数组赋初值,全部赋为-1,只要是不在序列中出现的数组即可
   }
  }
  for (int i = 0; i < len; ++i)
  {
   tempIndex = (arr[i] / n) % 10;//取到序列中的元素的个位/百位/.....的数字
   temp[tempIndex][i] = arr[i];//根据个位/百位/.....的数字确定容器
  }
  int j = 0;
  for (int x = 0; x < 10; ++x)
  {
   for (int y = 0; y < N; ++y)
   {
    if (temp[x][y] != -1)
    {
     arr[j] = temp[x][y];//将容器中数据放回原数组中去
     j++;
    }
   }
  }
 }
}
int main()
{
 int array[N] = { 6,8,1,500,4,7,500,10,9,3 ,999};
 bucket_sort(array, N);
 for (int i = 0; i < 10; ++i)
 {
  cout << array[i] << " ";
 }
 cout << endl;
 cin.get();
 return 0;
}

七、归并排序
归并排序:采用分而治之的思想对序列进行排序
1、将一组序列采用递归将其分到不能够再分为止
2、将不可分序列合并排序
代码实现:

#include<iostream>
using std::cin;
using std::endl;
using std::cout;
#define N 10
void _merge_in_arr(int arr[],int left,int mid,int right)//将序列合并并排序
{
int length=right-left+1;
int *pData=new int[length];
memset(pData,0,sizeof(int)*length);

int low=left;
int hig=mid+1;
int index=0;
while(low<=mid&&hig<=right)
{
while(low<=mid&&arr[low]<=arr[hig])
pData[index++]=arr[low++];
while(hig<=right&&arr[hig]<arr[low])
pData[index++]=arr[hig++];
}
if(low<=mid)
memcpy(&pData[index],&arr[low],sizeof(int) * (mid-low+1));
if(hig<=right)
memcpy(&pData[index],&arr[hig],sizeof(int) * (right-hig+1));
memcpy(&arr[left],pData,sizeof(int)*length);
}

void _merge(int arr[],int left,int right)//将序列拆分到不可再分为止
{
if(left>=right)return;
int mid=((right-left)>>1)+left;
_merge(arr,left,mid);
_merge(arr,mid+1,right);
_merge_in_arr(arr,left,mid,right);
}

void _merge(int arr[],int len)
{
_merge(arr,0,len-1);
}

int main()
{
int array[N]={9,8,1,5,3,2,1,5,3,1};
_merge(array,N);
for(int i=0;i<N;++i)
{
cout<<array[i]<<" ";
}
cout<<endl;
cin.get();
return 0;
}
内容概要:本文介绍了奕斯伟科技集团基于RISC-V架构开发的EAM2011芯片及其应用研究。EAM2011是一款高性能实时控制芯片,支持160MHz主频和AI算法,符合汽车电子AEC-Q100 Grade 2和ASIL-B安全标准。文章详细描述了芯片的关键特性、配套软件开发套件(SDK)和集成开发环境(IDE),以及基于该芯片的ESWINEBP3901开发板的硬件资源和接口配置。文中提供了详细的代码示例,涵盖时钟配置、GPIO控制、ADC采样、CAN通信、PWM输出及RTOS任务创建等功能实现。此外,还介绍了硬件申领流程、技术资料获取渠道及开发建议,帮助开发者高效启动基于EAM2011芯片的开发工作。 适合人群:具备嵌入式系统开发经验的研发人员,特别是对RISC-V架构感兴趣的工程师和技术爱好者。 使用场景及目标:①了解EAM2011芯片的特性和应用场景,如智能汽车、智能家居和工业控制;②掌握基于EAM2011芯片的开发板和芯片的硬件资源和接口配置;③学习如何实现基本的外设驱动,如GPIO、ADC、CAN、PWM等;④通过RTOS任务创建示例,理解多任务处理和实时系统的实现。 其他说明:开发者可以根据实际需求扩展这些基础功能。建议优先掌握《EAM2011参考手册》中的关键外设寄存器配置方法,这对底层驱动开发至关重要。同时,注意硬件申领的时效性和替代方案,确保开发工作的顺利进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值