数组的排序算法总结


一、选择法排序

选择法排序指每次选择所要排序的数组中的最大值(由大到小排序,由小到大排序则选择最小值)的数组元素,将这个数组元素的值与最前面没有进行排序的数组元素的值互换。
下面以数字9、6、15、4、2为例,对这几个数字进行排序,每次交换的顺序如表所示。
在这里插入图片描述
代码实例

#include <stdio.h>
int main()
{
	int i,j;
	int a[10];
	int iTemp; 
	int iPos; 
	printf("为数组元素赋值:\n");
	/*从键盘为数组元素赋值*/
	for(i=0;i<10;i++)
	{
		printf("a[%d]=",i);
		scanf("%d", &a[i]);	
	}
	/*从小到大排序*/
	for(i=0;i<9;i++) 				/*设置外层循环为下标0~8的元素*/
	{ 
		iTemp = a[i]; 				/*设置当前元素为最小值*/
		iPos = i;					/*记录元素位置*/
		for(j=i+1;j<10;j++) 		/*内层循环i+1到9*/
		{ 
			if(a[j]<iTemp) 			/*如果当前元素比最小值还小*/
			{ 
				iTemp = a[j];	 	/*重新设置最小值*/
				iPos = j; 			/*记录元素位置*/
			} 
		} 
		/*交换两个元素值*/
		a[iPos] = a[i]; 
		a[i] = iTemp; 
	}

	/*输出数组*/
	for(i=0;i<10;i++)
	{
		printf("%d\t",a[i]);			/*输出制表位*/
		if(i == 4)					/*如果是第5个元素*/
			printf("\n");		/*输出换行*/
	}

	return 0;						/*程序结束*/
}

二、冒泡法排序

冒泡法排序指的是在排序时,每次比较数组中相邻的两个数组元素的值,将较小的数(从小到大排列)排在较大的数前面。

下面仍以数字9、6、15、4、2为例,对这几个数字进行排序,每次排序的顺序如表所示。
在这里插入图片描述

#include<stdio.h>
#include <iostream.h>
int main()
{
	int i,j;
	int a[10];
	int iTemp; 
	printf("为数组元素赋值:\n");
	/*从键盘为数组元素赋值*/
	for(i=0;i<10;i++)
	{
		printf("a[%d]=",i);
		scanf("%d", &a[i]);	
	}
	/*从小到大排序*/
	for(i=1;i<10;i++) 				/*外层循环元素下标为1~9*/
	{ 
		for(j=9;j>=i;j--) 			/*内层循环元素下标为i~9*/
		{ 
			if(a[j]<a[j-1]) 		/*如过前一个数比后一个数大*/
			{ 
				/*交换两个数组元素的值*/
				iTemp  = a[j-1]; 
				a[j-1] = a[j]; 
				a[j]   = iTemp; 
			} 
		} 
	}

	/*输出数组*/
	for(i=0;i<10;i++)
	{
		printf("%d\t",a[i]);			/*输出制表位*/
		if(i == 4)					/*如果是第5个元素*/
			printf("\n");			/*输出换行*/
	}

	return 0;						/*程序结束*/
}
	

三、交换法排序

交换法排序是将每一位数与其后的所有数一一比较,如果发现符合条件的数据则交换数据。首先,用第一个数依次与其后的所有数进行比较,如果存在比其值大(小)的数,则交换这两个数,继续向后比较其他数直至最后一个数。然后在使用第二个数与其后面的数进行比较,如果存在比其值大(小)的数,则交换这两个数。继续向后比较其他数直至最后一个数,直至最后一个数比较完成。
下面以数字9、6、15、4、2为例,对这几个数字进行交换法排序,每次排序的顺序如表所示。

在这里插入图片描述

#include <stdio.h>
int main()
{
	int i,j;
	int a[10];
	int iTemp; 
	printf("为数组元素赋值:\n");
	/*从键盘为数组元素赋值*/
	for(i=0;i<10;i++)
	{
		printf("a[%d]=",i);
		scanf("%d", &a[i]);	
	}
	/*从小到大排序*/
	for(i=0;i<9;i++) 				/*外层循环元素下标为0~8*/
	{ 
		for(j=i+1;j<10;j++) 			/*内层循环元素下标为i+1到9*/
		{ 
			if(a[j] < a[i]) 			/*如果当前值比其他值大*/
			{ 
				/*交换两个数值*/
				iTemp = a[i]; 
				a[i]  = a[j]; 
				a[j]  = iTemp; 
			} 
		} 
	}

	/*输出数组*/
	for(i=0;i<10;i++)
	{
		printf("%d\t",a[i]);			/*输出制表位*/
		if(i == 4)					/*如果是第5个元素*/
			printf("\n");		/*输出换行*/
	}

	return 0;						/*程序结束*/
}

四、插入法排序

插入法排序较为复杂,其基本工作原理是抽出一个数据,在前面的数据中寻找相应的位置插入,然后继续下一个数据,直到完成排序。

下面以数字9、6、15、4、2为例,对这几个数字进行插入法排序,每次排序的顺序如表所示。
在这里插入图片描述

#include <stdio.h>
int main()
{
	int i;
	int a[10];
	int iTemp; 
	int iPos; 
	printf("为数组元素赋值:\n");
	/*从键盘为数组元素赋值*/
	for(i=0;i<10;i++)
	{
		printf("a[%d]=",i);
		scanf("%d", &a[i]);	
	}

	/*从小到大排序*/
	for(i=1;i<10;i++) 							/*循环数组中元素*/
	{ 
		iTemp = a[i]; 						/*设置插入值*/
		iPos = i-1; 
		while((iPos>=0) && (iTemp<a[iPos])) 	/*寻找插入值的位置*/
		{ 
			a[iPos+1] = a[iPos]; 				/*插入数值*/
			iPos--; 
		} 
		a[iPos+1] = iTemp; 
	}

	/*输出数组*/
	for(i=0;i<10;i++)
	{
		printf("%d\t",a[i]);			/*输出制表位*/
		if(i == 4)					/*如果是第5个元素*/
			printf("\n");		/*输出换行*/
	}

	return 0;						/*程序结束*/
}

五、折半法排序

折半法排序又称为快速排序,是选择一个中间值middle(在程序中,我们使用数组中间值),然后把比中间值小的数据放在左边,比中间值大的数据放在右边(具体的实现是从两边找,找到一对后进行交换)。然后对两边分别递归使用这个过程。
下面以数字9、6、15、4、2为例,对这几个数字进行折半法排序,每次排序的顺序如表所示。
在这里插入图片描述

#include <stdio.h>

void CelerityRun(int left, int right, int array[]);

int main()
{
	int i;
	int a[10];
	printf("为数组元素赋值:\n");
	/*从键盘为数组元素赋值*/
	for(i=0;i<10;i++)
	{
		printf("a[%d]=",i);
		scanf("%d", &a[i]);	
	}

	/*从小到大排序*/
	CelerityRun(0,9,a);

	/*输出数组*/
	for(i=0;i<10;i++)
	{
		printf("%d\t",a[i]);			/*输出制表位*/
		if(i == 4)					/*如果是第5个元素*/
			printf("\n");		/*输出换行*/
	}

	return 0;						/*程序结束*/
}

void CelerityRun(int left, int right, int array[])
{
	int i,j; 
	int middle,iTemp; 
	i = left; 
	j = right; 
	middle = array[(left+right)/2];				 /*求中间值*/
	do
	{ 
		while((array[i]<middle) && (i<right))	/*从左找小于中值的数*/
			i++;      
		while((array[j]>middle) && (j>left))	/*从右找大于中值的数*/ 
			j--; 
		if(i<=j)								/*找到了一对值*/ 
		{ 
			iTemp = array[i]; 
			array[i] = array[j]; 
			array[j] = iTemp; 
			i++; 
			j--; 
		} 
	}while(i<=j);				/*如果两边的下标交错,就停止(完成一次)*/ 

	/*递归左半边*/ 
	if(left<j) 
		CelerityRun(left,j,array); 
	/*递归右半边*/ 
	if(right>i) 
		CelerityRun(i,right,array);
}

六、排序算法的比较

在前面已经介绍了5种排序方法,那么在进行数组排序时应该使用哪一种方法呢?这就应该根据需要进行选择。下面对这5种排序方法进行一下简单的比较。
(1)选择法排序
选择法排序在排序过程中共需进行n(n-1)/2次比较,互相交换n-1次。选择法排序简单、容易实现,适用于数量较小的排序。
(2)冒泡法排序
最好的情况是正序,因此只要比较一次即可;最坏的情况是逆序,需要比较n^2次。冒泡法是稳定的排序方法,当待排序列有序时,效果比较好。
(3)交换法排序
交换法排序和冒泡法排序类似,正序时最快,逆序时最慢,排列有序数据时效果最好。
(4)插入法排序
此算法需要经过n-1次插入过程,如果数据恰好应该插入到序列的最后端,则不需要移动数据,可节省时间,因此若原始数据基本有序,此算法具有较快的运算速度。
(5)折半法排序
折半法排序对于较大的n时,是速度最快的排序算法;但当n很小时,此方法往往比其他排序算法还要慢。折半法排序是不稳定的,对应有相同关键字的记录,排序后的结果可能会颠倒次序。
插入法、冒泡法、交换法排序的速度较慢,但参加排序的序列局部或整体有序时,这种排序能达到较快的速度;在这种情况下,折半法排序反而会显得速度慢了。当n较小时,对稳定性不作要求时宜用选择排序,对稳定性有要求时宜用插入或冒泡排序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dlz0836

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值