形形色色的排序

一.最快最简单的排序:桶排序(简化版)

对于桶排序,其实非常简单,只是需要用一个一维数组便可以解决。

比如,我们需要对一串1~100范围内的数进行排序,现在给出这样的一串数:230,25,11,25。如果要对这五个数进行排序,我们首先就要开始构建出装这些数据的桶,因为开始说了范围为1~100,所以我们需要100个桶,但是为了方便桶的序号与我们的数据相同,所以一般选择定义一个a[101]这样的大桶,然后我们将每一个数组序号想象为一个桶,因为开始桶里面是没有东西的,所以我们将数组的初值都定义为0

接着我们就需要将我们的数据放进桶里面了,比如第一个数为2,那么a[2]就加一,即a[2]的值就从0变成了1,同理将后面的后面的数也放进桶之中,注意!因为25出现了两次,那么a[25]也会加两次。即a[25]的值会从0变成2

 

#include<stdio.h>
int main()
{
	int n,i=0,j=0;
	int a[101];//构建桶 。 
	
	for(i=0;i<101;i++)
	{
		a[i]=0;//清空桶里面的内容 。 
	}
	for(i=0;i<5;i++)
	{
		scanf("%d",&n);//依次录入5个数。 
		a[n]++;//放进对应的桶中。 
	}
	for(i=0;i<101;i++)//依次检验桶里面是否有东西 
	{
		for(j=0;j<a[i];j++)//看桶里装了几个数据 ,有几个打印几个。 
		{
			printf("%d ",i);//打印数据 
		}
	}
	return 0; 
 } 

1桶排序的核心代码示例

PS:这是升序,如果需要降序,只需要将打印的代码的 for(i=0;i<101;i++)改为for(i=100;i>0;i--)即可。桶排序是一种十分浪费空间的排序算法,需要排序数的范围越大,所开辟的空间越大;而且桶排序不能给小数排序。

二. 经典排序:冒泡排序

冒泡排序是一种非常经典的排序方式,也最常用的排序方法之一。

冒泡排序的基本思想是:每次比较相邻两个数的大小,如果他们的顺序错误,就把他们的位置交换。

 

 

2冒泡法图解

 

#include<stdio.h>
int main()
{
	int n,i,j,flag=0;
	int a[100];
	scanf("%d",&n);//输入一个N表示接下来将会有N个数进行排序。
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);//依次输入要排序的N个数。 
	 } 
	 for(i=0;i<=n-2;i++)//冒泡算法的核心代码,两个嵌套的循环。 
	 {	for(j=0;j<=n-i-2;j++)//N个元素需要N-1趟。 
	 	{
	 		if(a[j]>a[j+1])//比较相邻的两个元素,如果满足条件便交换。 
	 			{
				 flag=a[j];a[j]=a[j+1];a[j+1]=flag;
				 }
		 }
	} 
	  for(i=0;i<n;i++) 
	  printf("%d ",a[i]);//打印排好后的数据。 
	  return 0;
}

3冒泡排序代码

PS:因为冒泡排序使用了两个嵌套的循环,所以冒泡排序的时间复杂度较高。

三. 最常用的排序:快速排序

相比较于桶排序和冒泡排序,快速排序无论是在时间复杂度还是空间上都更加优秀。

假设现在我们对4 2 5 6 1 3”这6个数进行排序,首先我们先选定一个基准数,在这里我们选定4为基准数(随机选择,其他的都可以)。

4

2

5

6

1

3

 

 

接着我们就需要开始从序列的两端开始探测,假设j从序列的右边开始向左探测,i从序列的左边开始向右探测,j的任务是寻找比基准数小的元素,i的任务是寻找比基准数大的元素,注意,每一次探测,必须先从右边开始,即先从j开始。

j开始探测,发现了3比基准数小,标记,接着i开始探测,发现5比基准数大,标记。

4

2

5i

6

1

3j

 

 

ij标记的数互换,但是ij的位置不换。

4

2

3i

6

1

5j

 

 

ij继续探测,j发现了1i发现了6,互换。

4

2

3

1i

6j

5

 

 

然后j继续向左走,发现了1,注意,此时ij碰面了,这时我们只需要将基准数和i和碰面的数交换即可。

1

2

3

4

6

5

 

 

此时我们发现基准数左边都是比基准数小的数,右边全是比基准数大的数,然后用同样的方法来处理基准数两边的序列,即处理1 2 3”这个序列和“6 5”这个序列。

其实快速排序就是将选定的基准数归位,直到所有的基准数都归位,那么序列也就排好了。

 

 

#include<stdio.h>
int a[101],n;//定义两个全局变量,在子函数中使用。
void quicksort(int left,int right)//定义快排函数 
{
	int i,j,t,temp;
	if(left>right)
		return;
		
	temp=a[left];//temp中为基准数
	i=left;j=right;
	while(i!=j)
	{
		while(a[j]>=temp&&i<j)//j从右边开始向左找,记住一定先从右边开始。
			j--;
		while(a[i]<=temp&&i<j)//再从左边开始寻找。
			i++;
		if(i<j)//i和j没有相遇时,交换两个数的位置。 
		{
			t=a[i];a[i]=a[j];a[j]=t;
		 } 
	 } 
	 a[left]=a[i];a[i]=temp;
	 
	 quicksort(left,i-1);//利用递归,继续处理左边的序列。
	 quicksort(i+1,right);//利用递归,继续处理右边的序列。
	 return; 
 } 
 int main()
 {
 	int i,j;
 	scanf("%d",&n);//输入要参与排序的元素的个数。
	 for(i=1;i<=n;i++)
	 	{scanf("%d",&a[i]);}//输入参与排序的元素。
	quicksort(1,n);//调用快排函数。
	for(i=1;i<=n;i++)
		printf("%d ",a[i]);//打印排好序后的数列。 
 	return 0;
}

4快速排序代码

排序的算法还有很多,这里只是简单介绍了这三种。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值