上次我们说到了十种排序的前五种,这次我们来说说剩下的五种排序方式:
(1).基数排序
(2).计数排序
(3). 希尔排序
(4).选择排序
(5).归并排序
一、基数排序:
基数排序是将所有的数,比较它们各位数的大小,然后依次放到十个链表中去,最后按照顺序将它们取出来,最后再进行对十位的操作:一次知道位数最大的一个数比较才结束。
代码如下:
#include <stdio.h>
#include "slink.h"
void swap(int *pa,int *pb)
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void show(int arr[],size_t n)
{
int i=0;
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
void num_of_bit(int num,int bit)
{
int i;
for(i=1;i<bit&&num!=0;i++)
{
num = num/10;
}
return num%10;
}
void base_sort(int arr[],size_t n)
{
if(n<=1)
{
return;
}
int max = arr[0];
int i;
for(i=0;i<n;i++)
{
if(arr[i]>max)
{
max = arr[i];
}
}
Slink vect[10] = {};
for(i=0;i<10;i++)
{
vect[i] = slink_create();
}
int bit;
for(bit=1;max!=0;bit++,max/=10)
{
for(i=0;i<n;i++)
{
int n = num_of_bit(arr[i],bit);
slink_push_back(vect[n],arr[i]);
}
int j=0;
for(i=0;i<10;i++)
{
while(!slink_is_empty)
{
arr[j++] = slink_get_front(vect[i]);
slink_pop_front(vect[i]);
}
}
}
for(i=0;i<10;i++)
{
slink_destory(vect[i]);
}
}
二、计数排序:
计数排序就是找出数组中的最大值和最小值,数组的个数cnt不会超过最大值减去最小值个数加一,再定义另一个数组长度为cnt,并全部制0,其下标为原数组减去最小值。
代码段如下:
#include <stdio.h>
#include <stdlib.h>
void swap(int *pa,int *pb)
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void show(int arr[],size_t n)
{
int i=0;
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
void count_sort(int arr[],size_t n)
{
int max = arr[0],min=arr[0];
int i;
for(i=0;i<n;i++)
{
if(arr[i]>max)
{
max = arr[i];
}
if(arr[i]<min)
{
min = arr[i];
}
}
int cnt = max-min+1;
int brr[cnt];
for(i=0;i<cnt;i++)
{
brr[i] = 0;
}
for(i=0;i<n;i++)
{
brr[arr[i]-min]++;
}
int j;
for(i=0;j<n;i++)
{
while(brr[i]>0)
{
arr[j++] = i+min;
--brr[i];
}
}
}
int main()
{
int arr[] = {5,3,7,2,6,0,4,8,7};
size_t n = sizeof(arr)/sizeof(arr[0]);
show(arr,n);
count_sort(arr,n);
show(arr,n);
return 0;
}
三、希尔排序
希尔排序就是将数组每次进行一定步长的分隔,然后进行插入排序。
代码段如下:
在这里插入代码片
```#include <stdio.h>
#include <stdlib.h>
void swap(int *pa,int *pb)
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void show(int arr[],size_t n)
{
int i=0;
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
void shell_sort(int arr[],size_t n)
{
int i,j,step;
for(step=n/2;step>0;step/=2)
{
for(i=step;i<n;i++)
{
int key = arr[i];
for(j=i-step;j>=0 && arr[j]>key;j-=step)
{
arr[j+step] = arr[j];
}
if(j+step != i)
{
arr[j+step] = key;
}
}
}
}
int main()
{
int arr[]={7,4,6,8,0,2,9,1,3,5};
size_t n = sizeof(arr)/sizeof(arr[0]);
show(arr,n);
shell_sort(arr,n);
show(arr,n);
return 0;
}
四、选择排序:
在数组中定一个一个下标为max,与后面的元素依次进行比较,如果元素值大于max的值,则将其下标定义为max,知道和最后一个比较完成,再接着下一次循环。
代码段如下:
#include <stdio.h>
#include <stdlib.h>
void swap(int *pa,int *pb)
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void show(int arr[],size_t n)
{
int i=0;
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
void chose_sort(int arr[],size_t n)
{
int i,j;
for(i=0;i<n;i++)
{
int max = 0;
for(j=1;j<n-i;j++)
{
if(arr[j]>arr[max])
{
max = j;
}
}
if(max != n-1-i)
{
swap(&arr[max],&arr[n-1-i]);
}
}
}
int main()
{
int arr[] = {5,4,7,6,1,3,2,9,8,0};
size_t n = sizeof(arr)/sizeof(arr[0]);
show(arr,n);
chose_sort(arr,n);
show(arr,n);
return 0;
}
五、归并排序
归并排序就是找到数组中间值,将数组分为左边和右边两个部分,然后分别对它们之中的值进行排序,然后将两个数组有序合并插入排序。
代码段如下:
//归并排序
#include <stdio.h>
#include <stdlib.h>
void swap(int *pa,int *pb)
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void show(int arr[],size_t n)
{
int i=0;
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
void merger(int arr[],size_t n)
{
int i;
int mid = (0+n-1)/2;
int *p = calloc(mid+1,sizeof(int));
for(i=0;i<=mid;i++)
{
p[i] = arr[i];
}
i=0;
int j=0,k=mid+1;
while(j<=mid && k<n)
{
if(p[j]<arr[k])
{
arr[i++] = p[j++];
}else{
arr[i++] = arr[k++];
}
}
while(j<=mid)
{
arr[i++] = p[j++];
}
}
void merger_sort(int arr[],size_t n)
{
if(n<=1)
{
return;
}
int mid = (0+n-1)/2;
if(mid+1>1)
{
merger_sort(arr,mid+1);
}
if(n-mid-1>1)
{
merger_sort(arr+mid+1,n-mid-1);
}
merger(arr,n);
}
int main()
{
int arr[]={5,7,3,2,6,1,9,3,0,8};
size_t n = sizeof(arr)/sizeof(arr[0]);
show(arr,n);
merger_sort(arr,n);
show(arr,n);
return 0;
}
以上就是我所列举的十种排序方法。