c实现的各种排序

来源:互联网 发布:php 获取请求头部信息 编辑:程序博客网 时间:2024/05/16 02:02

虽然以前学习Java的时候对各种排序都进行学习和掌握,自己觉得也挺简单,每次用到的时候,都是去copy书上或者网上现成的,这两天在准备C语言考试的时候,才发现自己踏踏实实一行一行敲出来的代码运行不出正确结果来。当时就忍不了了。好多招聘面试都是开口就问数据结构的知识,而数据结构里面最简单的就是各种排序,这要不先搞定,就没法玩了。所以决定重新温习一遍。(这里全是以升序来讲解的,降序只需更改比较大小的那句代码就行)

但是在讲排序之前呢,不得不说说swap函数的写法,如果是值传递的话交换不会成功。如下:

void swap(int a, int b ){     int temp=a;    a=b;    b=temp;}       

为什么呢,因为这里实参和形参拥有不同的内存空间,在执行的时候是把实参先复制到形参的内存空间中去,在swap里面只是对形参进行了交换,而我们真正想交换的实参数据却没有任何改变。

所以可以用传地址(即指针)的方式来进行交换,这样就都是对同一内存空间进行操作了。

void swap(int *p1, int *p2){    int temp = *p1;    *p1 = *p2;    *p2 = temp;}

1、选择排序
所谓选择,顾名思义就是以选择的方式,即每次通过比较选出一个最小的数的索引,然后把该索引处的数组元素放到适当位置。代码如下:

void select(int a[], int len){    int i, j, index;    for(i=0; i<len; i++)    {        index=i;        for(j=i+1; j<len; j++)            if(a[j]<a[index])                index=j;        swap(a+i, a+index);    }}

2、插入排序
插入排序的思路是每次把一个数插入到已排好序的序列里面去,例如,一开始我们把数组的第一个元素看做已排好的序列(尽管只有一个元素),然后把数组的第二个元素通过比较插在该序列的适当位置,以此类推,当做第n次插入的时候,那么前n-1个数就已经是排好序的了。代码如下:

void insert(int a[], int len){    int i, j, temp;    for(i=1; i<len; i++)    {        if(a[i]<a[i-1])        {            temp=a[i];            j=i;            while(j>0 && a[j-1]>temp)            {                a[j]=a[j-1];                j--;            }            a[j]=temp;        }    }}

3、冒泡排序
对于冒泡排序个人觉得是最好理解也是最好写的,四行代码就搞定了。不过还是说说这个过程吧,从开头依次进行两两比较,判断是否交换,所以一次冒泡的结果就是得到一个最大的放在末尾。代码如下:

void bubble(int a[], int len){    int i, j;    for(i=len-1; i>=0; i--)        for(j=0; j<i; j++)            if(a[j]>a[j+1])                swap(a+j, a+j+1);}

4、快速排序
快速排序采用递归的思想,就是先取一个参考值,通过一趟排序将要排序的数据分割成独立的两部分,把比参考值小的放到其前面,比参考值大的放到其后面,然后再按此方法对这两部分数据分别进行快速排序。代码如下:

void quick(int a[], int len){    int i=0, j=len-1;    int val=a[0];    if(len>1)    {        while(i<j)        {            for(; j>i; j--)                if(a[j]<val)                {                    a[i++]=a[j];                    break;                }            for(; i<j; i++)            {                if(a[i]>val)                {                    a[j--]=a[i];                    break;                }            }        }    }    a[i]=val;    quick(a, i);    quick(a+i+1, len-i-1);}

5、归并排序
归并排序的基本思路是,将数组分成 两组A,B,如果这两组组内的数据都是有序的,那么就可以很方便的将这两组数据进行排序。如何让这两组组内数据有序?可以将A,B组各自再分成两组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的两个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。代码如下:

/*复制数组,source:源数组,dest:目标数组,len:源数组长度,  first:目标数  组起始位置  */void copy(int source[], int dest[],int len,int first)  {      int i;      int j=first;      for(i=0;i<len;i++)      {          dest[j] = source[i];          j++;      }  }//归并过程void merge(int a[],int left,int right)  {      int begin1 = left;      int mid = (left+right)/2 ;      int begin2 = mid+1;      int k=0;      int newArrayLen = right-left+1;      int *b = (int*)malloc(newArrayLen*sizeof(int));      while(begin1<=mid && begin2<=right)      {          if(a[begin1]<=a[begin2])              b[k++] = a[begin1++];          else              b[k++] = a[begin2++];      }      while(begin1<=mid)          b[k++] = a[begin1++];      while(begin2<=right)          b[k++] = a[begin2++];      copyArray(b,a,newArrayLen,left);      free(b);  }  //递归调用void mergeSort(int a[],int left,int right)  {      int i;     if(left < right)  // 保证至少有两个元素     {          i = (left+right)/2;          mergeSort(a,left,i);          mergeSort(a,i+1,right);          merge(a,left,right);      }  }  
0 0
原创粉丝点击