学习排序算法时写的,采用C实现,缺陷在于没有对算法复杂度和时间运行进行分析~不过代码很用心注释了的,欢迎指正。
//排序算法
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int n,i,c,Way; //(选10长度的序列报个小错误。。。,应该不是函数内部问题
void Bubblingsort(int a[],int n);//冒泡排序
void Insertsort(int a[],int n);//直接插入排序
void Selectsort(int a[],int n);//选择排序
int Mergesort(int a[],int head,int tail);//归并排序
int Sort(int a[],int head, int mid,int tail); //归并排序中排序函数
void Quicksort(int a[],int head,int tail);//快速排序
void CountSort(int a[],int len,int c);//计数排序
void RadixSort(int a[], int n);//基数排序
void Sort(int a[],int n,int d);//基数排序中排序函数
int GetDValue(int value, int d);//基数排序中取位函数
void Hillsort(int a[],int head,int tail);//希尔排序
void print_arry(int *a,int n);//打印函数
void choose(int arr[],int n,int i,int c);
printf ("1、冒泡排序\n");
printf ("2、直接插入排序\n");
printf ("3、选择排序\n");
printf ("4、归并排序\n");
printf ("5、快速排序\n");
printf ("6、计数排序\n");
printf ("7、基数排序\n");
printf ("8、希尔排序\n");
printf ("请选取需要测试的排序方法 Way=");
scanf ("%d", &Way);
if(Way>8&&Way<1)
{
printf("无法进行排序\n");
exit(0);
}
printf ("所取排序随机数个数 n=");
scanf ("%d", &n);
printf ("测试取整数范围 c=");
scanf ("%d", &c);
printf("\n");
n=n-1;
int *arr = (int *)malloc(sizeof(int) * n);
srand (time (0));
for (i = 0; i<=n; i++)
{
arr[i] = rand() % c;
}
printf ("随机生成数值为0~%d的数组...\n",c);
printf ("初始化数组: ");
print_arry(arr, n);
printf ("排序后的数组:");
switch(Way)
{
case 1:
Bubblingsort(arr,n);//冒泡排序
break;
case 2:
Insertsort(arr,n);//直接插入排序
break;
case 3:
Selectsort(arr,n);//选择排序
break;
case 4:
Mergesort(arr,0,n);//归并排序
break;
case 5:
Quicksort(arr,0,n); //快速排序
break;
case 6:
CountSort(arr,n,c);//计数排序
break;
case 7:
RadixSort (arr,n);//基数排序
break;
case 8:
Hillsort(arr,0,n); //希尔排序
break;
default:
break;
}
print_arry(arr, n);
return 0;
system ("pause");
}
//冒泡排序:
void Bubblingsort(int a[],int n)
{
int i,j,t;
for(i=0;i<=n;i++)
{
for(j=0;j<=n-1;j++)
{
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
//直接插入排序:
void Insertsort(int a[],int n) //1、传入数组a[]和其长度n
{
int i,t,m;
for(i=1;i<=n;i++)
{
t=a[i];
//2、以t=a[i]记录待插入的值
for(m=i;m>0;m--) //3、开始往前循环,当未搜索到比a[i]小的值a[m-1],每一次通过 a[m]=a[m-1]将a[m-1]向后移位,
//当搜索到比a[i]小的值a[m-1],那么m的值即应为a[i]在已排序列中的正确位置。
{
if(t<a[m-1])
{
a[m]=a[m-1];
}
else
break;
}
a[m]=t; //4、找到m值,即可将记录好的t值赋予a[m],完成一次插入
}
}
//选择排序:每一趟排序,从未排序中最小值与未排序的第一个数字交换位置。
void Selectsort(int a[],int n)
{
int i,d,m,t;
for(i=0;i<=n;i++)
{
d=i; //1、通过d=i记录i的值。
for(m=n;m>i;m--) //2、通过遍历,在未排序的序列中,通过比较找出最小值并使d等于序列中最小值的下标。
{
if(a[d]>a[m])
{
d=m;
}
}
t=a[i];
a[i]=a[d]; //3、通过交换位置,使最小值换到未排序序列首位。
a[d]=t;
}
}
//归并排序:
int Sort(int a[],int head, int mid,int tail) //1、传递待排序列a、序列a的起始下标head、分段中点mid、 末尾下标tail
{ int i=head,j=mid+1,k=0;
int temp[1000]={0}; //2、暂设临时数组(最好用申请内存malloc合理分配空间,此处仅供测验)
for(i=head,j=mid+1,k=head;k<=tail;) //3、待排序列被mid分为两段,i、j分别为一段的起始点,开始排序
{
if(i==mid+1) //4、当i=mid+1,左段已全部放到临时数组temp,此时只需从j后面的全放到临时数组temp
{
temp[k]=a[j];
j++;
k++;
}
if(j==tail+1) // 5、同上一注释
{
temp[k]=a[i];
k++;
i++;
}
if(i<=mid&&j<=tail) //6、(排序第一步必从这里开始时)此时条件下, 比较a[i]的a[j]的大小,小的便放到临时数组temp[],然后下标自加 1 ,程序循环,完成序列a[]的排序。
{
if(a[i]<a[j])
{
temp[k]=a[i];
k++;
i++;
}
else
{
temp[k]=a[j];
k++;
j++;
}
}
}
for(i=head;i<=tail;i++)
a[i]=temp[i];
}
int Mergesort(int a[],int head,int tail)
{
int mid;
mid=(tail+head)/2;
if(mid>head) //7、当(mid>head)>0,说明此时序列只有一个数,此时无需进行序列排序
{
mid=(tail+head)/2;
Mergesort(a,head,mid);
Mergesort(a,mid+1,tail); //9、进行递归(通过观察程序可以发现,此处将一直往下一直找到最小的序列,即两个数字的时候,才会退出if,进行Sort函数排序,排好序,然后两个排序好的两个数字(一共四个),以此类推。
} //可以看出归并排序是从最底层往上排。
Sort(a,head,mid,tail);
}
//快速排序:
void Quicksort(int a[],int head,int tail) //1、传入待排序数组a[],数组a[]首个数值下标head,末尾数值下标tail。
{ int i=head+1,j=tail,k=0,key,t=0;
key=head; //2、令key等于数组首下标。
for(k=0;k<tail-head;) //3、以k从0开始循环,循环数组长度tail-head次。
{
if(key<=i) //4、当key<=i,说明key需要从j往前搜索。
{
if(a[key]>a[j]) //5、从j开始搜索时,当满足a[key]>a[j],那么互换位置,然后令key=j;此时完成一次搜索,需k++。
{
t=a[key];
a[key]=a[j];
a[j]=t;
key=j;
k++;
}
else //6、不满足条件时,令j--,往前继续搜索,此时也完成一次搜索,需k++。
{
j--;
k++;
}
}
if(key>i) //7、key>i,说明key需要从i往后搜索。
{
if(a[key]<a[i]) //8、从i开始搜索时,当满足a[key]<a[j],那么互换位置,然后令key=i;此时完成一次搜索,需k++
{
t=a[key];
a[key]=a[i];
a[i]=t;
key=i;
k++;
}
else //9、不满足条件时,令i++,往后继续搜索,此时也完成一次搜索,需k++。
{
i++;
k++;
}
}
} //(程序每一次搜索都会k++,当判断k在刚好下一刻大于序列长度时,i==j。循环结束。
if((key-1)>0) //10、当(key-1)>0,递归调用qupicksort函数,当 (key-1)<0,说明此时序列a[0]~a[key]只有两个数,此时停止递归。
Quicksort(a,0,key-1);
if(key+1<tail) //11、当key+1<tail,递归调用qupicksort函数,理由参考注释10 (判断条件我们可以从排三个数去想)
Quicksort(a,key+1,tail);
}
//计数排序:
int CountSort(int a[],int len,int c)
{
int *Count= NULL;
Count = (int*)malloc(sizeof(int)*c);
int *Sort=NULL;
Sort = (int*)malloc(sizeof(int)*len);
for(int i=0;i<=c;i++)
{
Count[i]=0; //1、初始化计数数组
}
for(int i = 0;i<=len;i++) //2、统计i的次数
{
Count[a[i]]++;
}
for(int i = 1; i<c; i++) //3、对所有的计数累加,这一步目的是为了让Count的值和放排序的数组Sort的下标建立联系。
{
Count[i] += Count[i-1];
}
for(int i = len; i>=0; i--) //4、每一次,我们以a[i]为Count[]下标,取得Count[]的值 ,然后让Count[]-1的值作为Sort[]的下标,
{ // 再给对应的Sort[]赋a[i]的值,此时,a[i]的值便会储存到Sort正确的序列位置。 排序完毕。
Sort[Count[a[i]]-1] = a[i];
Count[a[i]]--;
}
for(int i=len;i>=0;i--)
{
a[i]=Sort[i];
}
free(Count);
free(Sort);
}
//基数排序:
void RadixSort(int a[], int n) // 1、调用排序函数,每一次移位,从低到高进行排序。最后得到最终的正确序列
{
int i,WIDTH=4;
void Sort(int a[], int n, int d);
for (i = 0; i < WIDTH; i++)
{
Sort(a, n, i);
}
}
void Sort(int a[],int n,int d) // 2、 传递进待排序数组a[]、 数组长度、需要排序的基数位
{
int i, j, x,MAXK=10, k[MAXK] = {0};
int *ip = (int *)malloc(n * sizeof (int));
int *bp = (int *)malloc(n * sizeof(int));
int GetDValue(int value, int d);
for (i = 0; i <=n; i++) //3、调用GetDValue,取得数组a[]的值的第d位数字,存入数组k[i]中
{
ip[i] = GetDValue(a[i], d);
k[ip[i]]++;
}
for (j = 1; j < MAXK; j++) //4、对数组k[]进行累加
{
k[j] += k[j-1];
}
for (i = n; i >= 0; i--) // 5、每一次,我们以ip[i]为k[]下标,取得k[]的值 ,然后让k[]-1的值作为bp[]的下标,
{ // 再给对应的bp[]赋a[i]的值,此时,ip[i]的值便会储存到bp正确的序列位置。 排序完毕。
bp[k[ip[i]] - 1] = a[i];
k[ip[i]]--;
}
for (i = 0; i <=n; i++)
{
a[i] = bp[i];
}
free(ip);
free(bp);
}
int GetDValue(int value, int d) //获取一个数第d位数的值,位数索引从0开始
{
int MAXK=10;
for (;d > 0 && value > 0; d--)
{
value = value / MAXK;
}
return value % MAXK;
}
//希尔排序,详情参照归并递归思想,和直接插入排序注释。
void Hillsort(int a[],int head,int tail)
{
int mid;
void Insertsort(int a[],int n);
if((tail-head)>0)
{
mid=(tail+head)/2;
Hillsort(a,head,mid);
Hillsort(a,mid+1,tail);
}
Insertsort(a,tail);
}
void print_arry(int *a,int n)
{
int i;
for(i = 0; i<=n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}