C语言常见6大排序

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱写代码的马良

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值