#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 10
#define SWAP(A,B) (A)^=(B);(B)^=(A);(A)^=(B);
//创建数组
int * CreateArray()
{
//定义随机数
srand((unsigned int)time(NULL));
//创建数组
int *p=(int *)malloc(sizeof(int)*MAXSIZE);
memset(p,0,sizeof(int)*MAXSIZE);
int i;
for(i=0;i<MAXSIZE;i++)
p[i]=rand()%100+1;
return p;
}
//冒泡排序
void sort1(int *p,int len)
{
int i,j;
for(i=0;i<len-1;++i)
{
for(j=0;j<len-i-1;++j)
{
if(p[j]>p[j+1])
{
SWAP(p[j],p[j+1]);
}
}
}
}
//选择排序
void sort2(int *p,int len)
{
int i,j,k;
for(i=0;i<len-1;i++)
{
k=i;
for(j=k+1;j<len;j++)
{ //从小到大排序,找出最小下标
if(p[k]>p[j])
{
k=j;
}
}
//不相等,交换
if(k!=i)
{
SWAP(p[k],p[i]);
}
}
}
//插入排序
void sort3(int *p,int len)
{
int i,j,tmp;
//将数组分为2组,一组有序,一组无序,默认从下标为1的数组开始分组
//循环无序的数组
for(i=1;i<len;i++)
{
if(p[i]<p[i-1])
{
tmp=p[i];//带插入数值放入临时变量
//循环有序的数组,
for(j=i-1;j>=0&&tmp<p[j];--j)
{
//元素后移
p[j+1]=p[j];
}
//找到符合位置,插入
p[j+1]=tmp;
}
}
}
//希尔排序
void sort4(int *p,int len)
{
int i,j,k,tmp;
int g=len;//分组
do
{
g=g/3+1;
//循环组
for(i=0;i<g;++i)
{
//循环无序的数组
for(j=i+g;j<len;j+=g)
{
if(p[j]<p[j-g])
{
tmp=p[j];
//循环有序数组
for(k=j-g;k>=0&&tmp<p[k];k-=g)
{
p[k+g]=p[k];
}
p[k+g]=tmp;
}//end if
}//end for
}
}while(g>1);
}
//快速排序,从小到达排序
void sort5(int *p,int start,int end)
{
int i=start;
int j=end;
int tmp;
if(i<j)
{ tmp=p[i];//设定一个基准数
while(i<j)
{
//因为左边有槽,从数组的右边找出比基准数小的数
//从小到大,右边下标左移。找出比基准数小的数,
while(i<j&&tmp<p[j])
{
j--;//一直左移
}
//填充左边的坑,此时j右边出现一个坑
if(i<j)
{
p[i]=p[j];
i++;
}
//因为数组右边有槽,从数组的左边找出比基准数大的数
//从小到大,左边下标右移。找出比基准数大的数,
while(i<j&&tmp>p[i])
{
i++;//一直右移
}
//填充刚才右边j的坑,此时i左边出现一个坑
if(i<j)
{
p[j]=p[i];
j--;
}
}//end while
//小余tmp的在左边,大于tmp的在右边
p[i]=tmp;基准数填充坑
//分组,递归调用
//基准数左边递归
sort5(p,start,i-1);
//基准数右边递归
sort5(p,i+1,end);
}
}
//数组打印
void print(int *p,int len)
{
int i;
for(i=0;i<len;i++)
printf("%-3d",p[i]);
puts("");
}
void test01()
{
int *p=CreateArray();
printf("初始化\n");
print(p,MAXSIZE);
printf("冒泡排序\n");
sort1(p,MAXSIZE);
print(p,MAXSIZE);
}
void test02()
{
int *p=CreateArray();
printf("初始化\n");
print(p,MAXSIZE);
printf("选择排序\n");
sort2(p,MAXSIZE);
print(p,MAXSIZE);
}
void test03()
{
int *p=CreateArray();
printf("初始化\n");
print(p,MAXSIZE);
printf("插入排序\n");
sort3(p,MAXSIZE);
print(p,MAXSIZE);
}
void test04()
{
int *p=CreateArray();
printf("初始化\n");
print(p,MAXSIZE);
printf("希尔排序\n");
sort4(p,MAXSIZE);
print(p,MAXSIZE);
}
void test05()
{
int *p=CreateArray();
printf("初始化\n");
print(p,MAXSIZE);
printf("快速排序\n");
sort5(p,0,MAXSIZE-1);
print(p,MAXSIZE);
}
void mergeArr(int *p,int start,int mid,int end,int *tmp)
{
//第一个数组的下标
int i_start=start;
int i_end=mid;
//第二个数组的下标
int j_start=mid+1;
int j_end=end;
int length=0;
//2个有序的数组合并
while((i_start<=i_end)&&(j_start<=j_end))
{
if(p[i_start]<p[j_start])
{
tmp[length]=p[i_start];
length++;
i_start++;
}
else
{
tmp[length]=p[j_start];
length++;
j_start++;
}
}
//多余的数直接从数组拷贝
while(i_start<=i_end)
{
tmp[length]=p[i_start];
i_start++;
length++;
}
//多余的数直接从数组拷贝
while(j_start<=j_end)
{
tmp[length]=p[j_start];
j_start++;
length++;
}
//将tmp中的数直接拷贝至数组
int i;
for(i=0;i<length;++i)
{
p[i+start]=tmp[i];
}
}
void sort6(int *p,int start,int end,int *tmp)
{
//递归结束条件即为元素为1个的时候不分组(级下标指向同一个元素的时候就返回)
if(start>=end)
{
return;
}
//分组
int mid=(start+end)/2;
//左边递归分组
sort6(p,start,mid,tmp);
//右边递归分组
sort6(p,mid+1,end,tmp);
//分组后合并
mergeArr(p,start,mid,end,tmp);
}
void test06()
{
int *p=CreateArray();
printf("初始化\n");
print(p,MAXSIZE);
printf("归并排序\n");
//准备临时空间
int *tmp=(int *)malloc(sizeof(int)*MAXSIZE);
sort6(p,0,MAXSIZE-1,tmp);
print(p,MAXSIZE);
}
int main(void)
{
// test01(); //冒泡排序
//test02(); //选择排序
//test03(); //插入排序
//test04(); //希尔排序
//test05(); //快速排序
test06(); //归并排序
return 0;
}
C语言常见6大排序
最新推荐文章于 2023-01-23 18:01:51 发布