c语言之排序算法(一)

C语言之简单排序算法(一)

        排序算法是学习算法的开始,我们有时需要通过排序对数据进行处理。根据需要排序的数据多少和对数据处理的要求,我们可以用不同的排序算法。就此我根据自己的理解和搜集的资料,把c语言常用的几种简单排序算法整理出来。

一、冒泡排序

      在冒泡排序方法中,数字列表被分为两个子列表:已排序的和未排序的。就如同它的名字一样,最小或最大的元素通过冒泡的方法选出来并移到已排序的列表中,而这里的冒泡是指通过相邻的数据元素的交换,每次只排好一个元素。所以也就是说,一个含有n个元素的列表,需要进行n-1轮来完成排序。

如下图是从小到大排序的第一趟冒泡示例:

而冒泡排序用c语言写出来也是很简单很容易理解的,但是其时间复杂度高,这里嵌套了一次for循环。

代码如下:
#include<stdio.h>
int main(void) 
{
	int a[100],i,j,t,n;
	scanf("%d",&n);//输入要排序的数据个数 
	for(i=0;i<n;i++)
	scanf("%d",&a[i]);
	//开始排序 
	for(i=0;i<n;i++)
	{
		for(j=0;j<n-i-1;j++)
		{
			if(a[j]>a[j+1])
			{
				t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}	 
	}
	for(i=0;i<n;i++)
	printf("%d ",a[i]);//输出结果 
	return 0; 
}


二、快速排序

         快速排序是对冒泡排序的一种改进,它是通过一趟排序将要排序的数据分割成两部分,其中一部分的所有数据都要比另外一部分的所有数据都要小,然后再按照此方法对这两部分数据分别进行快速排序,这个排序过程可以看成递归。
            下面我举个简单例子来说明一下:

            如一组数:3 2 7 6 1 4
            a).先把第一个元素3取出来,用3依次与其他元素进行比较,如果有比3小的数字就放在3的前边,比3大的数字就放在3的  后边。第一趟排序后变成:2 1 3 7 6 4
            b).对前半部分[2 1]继续进行快速排序,重复步骤a变成:[1 2];
                 对后面部分[7 6 4]也进行同样的快速排序,变成:[6 4 7];
            c).上面的前半部分已排好序,只用看后半部分[6 4 7]再重复步骤a得到:[4 6 7];
                 此时整组数的顺序为:1 2 3 4 6 7 ,总的排序也到此完成。

          下图是一个快速排序的动态图:
           
          
           快速排序的时间主要耗费在划分操作上,对长度为n的区间进行划分要比较n-1次。它用代码敲出来是这样:
#include <stdio.h>
#include <stdlib.h>
#define N 6
int partition(int arr[], int low, int high)
{
    int key;
    key = arr[low];//定义一个关键元素 
    while(low<high){
        while(low <high && arr[high]>= key )
            high--;
        if(low<high)
            arr[low++] = arr[high];
        while( low<high && arr[low]<=key )
            low++;
        if(low<high)
            arr[high--] = arr[low];
    }
    arr[low] = key;
    return low;//返回的low就是满足它左边的值比low小,右边的值比low大 
}
//使用递归的方式对数组进行快速排序 
void quick_sort(int arr[], int start, int end)
{
    int pos;
    if (start<end){
        pos = partition(arr, start, end);
        quick_sort(arr,start,pos-1);
        quick_sort(arr,pos+1,end);
    }
    return;
}
int main(void)
{
    int i;
    int arr[N]={32,12,7, 78, 23,45};
    printf("排序前 \n");
    for(i=0;i<N;i++)
        printf("%d\t",arr[i]);
    quick_sort(arr,0,N-1);
    printf("\n 排序后 \n");
    for(i=0; i<N; i++)
        printf("%d\t", arr[i]);
    printf ("\n");
    system("pause");
    return 0;
} 

这里用了三个函数,代码相对于冒泡排序要难一些,但其时间复杂度要比冒泡低很多。

三、选择排序

         选择排序也是把数字列表分成两个子列表(已排序的和未排序的),和冒泡排序一样,每一轮都把最大或最小的元素筛选出来放在相应位置上,但是对于每一轮,选择排序是比较当前项和第n项,而冒泡是每次比较和移动相邻的两项。 一个含有n个元素的列表,也需要进行n-1轮来完成排序。
            为了更直观地理解选择排序请看下图:
          

这是选择排序的第一趟,之后也是按照上述步骤来。用代码来表示选择排序也用到了两重循环,如下:
#include<stdio.h>
#define N 10 
int main(void)
{
	int a[N];
	int i,j,t;
	for(i=0;i<N;i++)
	scanf("%d",&a[i]);//输入要排序的数据 
	//开始排序 
	for(i=0;i<N-1;i++) 
	   for(j=i+1;j<N;j++)
	   {
	   	  if(a[i]>a[j])
	   	  {
	   	  	t=a[i];
	   	  	a[i]=a[j];
	   	  	a[j]=t;
		  } 
	   }
	for(i=0;i<N;i++)
	printf("%d ",a[i]);
	return 0;
}

选择排序也是十分基础的,它比冒泡排序要快些,也是很容易理解和掌握的。

四、插入排序

         我们经常在扑克牌游戏中使用插入排序,把每张拿到的牌插入手中合适的位置,以便手中的牌以一定的顺序排列。而对数据进行插入排序也是如此,在每轮,把未排序子列表中的第一个元素转移到已排序子列表中,并且插入合适的位置。一个含有n个元素的列表至少需要n-1轮排序。
            下面时插入排序的示意图:

           

 

          在此我就不展示插入排序的代码了,以上就是四种简单的排序算法,如果要排序的列表中有多于几百个元素,那就不要使用除了快速排序的这些算法,应该使用更高效的算法如堆排序、Shell排序、桶排序、合并排序、基排序等。这些我将会下次为大家介绍。


猜你喜欢

转载自blog.csdn.net/wangaiji/article/details/79936127