冒泡,选择,插入排序优化,堆排序和qsort的用法

受到宫学长讲座的启发,学到不少的排序方法,所以也想记下来总结一下。所有排序默认都是从大到小排序

冒泡排序的优化

#include<stdio.h>
void swap(int *a,int *b)
void bubble1_sort(int *a,int len);
void bubble2_sort(int *arr,int n);
void bubble3_sort(int *arr,int len);
int main()//立flag优化
{
    int a[]={10,9,8,7,6,5,4,3,2,1};
    bubble3_sort(a,10);
    for(int i=0;i<10;i++)
        printf("%d ",a[i]);
    putchar('\n');
}
void bubble1_sort(int *a,int len)
{
    int flag=1;
    for(int i=0;i<len&&flag;i++)
    {
        flag=0;
        for(int j=0;j<len-i-1;j++)
        {
            if(a[j]>a[j+1])
            {
                flag=1;
                swap(&a[j],&a[j+1]);
            }
        }
    }
}
void bubble2_sort(int *arr,int n)
{
    int index=0;
    int len=n-1;
    for(int i=0;i<n;i++)
    {
        index=0;
        for(int j=0;j<len;j++)
        {
            if(arr[j]>arr[j+1])
            {
                index=j;//记住每次最后交换的序列
                swap(&arr[j],&arr[j+1]);
            }
        }
        len=index;//每次一趟就会有一个数排序,
                //所以就只需要到最后交换的地方就可以了
    }
}

void bubble3_sort(int *arr,int len)//鸡尾酒排序,两边同时进行
{
    int right=len-1;
    int left=0;

    while(left<right)
    {
        for(int i=left;i<right;i++)//在左边找出最大元素
        {
            if(arr[i]>arr[i+1])
                swap(&arr[i],&arr[i+1]);
        }
        right--;//右边最大数已经有了
        for(int i=right;i>left;i--)//在右边找到最小的元素
        {
            if(arr[i-1]>arr[i])
                swap(&arr[i-1],&arr[i]);
        }
        left++;//左边最小数已经有了

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

选择排序优化

#include<stdio.h>
void swap(int *a,int *b)
void select_sort(int A[],int n);
int main()
{
    int a[10]={1,2,3,4,5,6,7,8,9,10};
    select_sort(a,10);
    for(int i;i<10;i++)
        printf("%d ",a[i]);
}

void select_sort(int *arr,int len)//优化的方法就是一次性选出最大和最小
{
    int left=0;
    int right=len-1;
    int max=0,min=0;

    for(int left=0,right=len-1;left<right;left++,right--)//让区间左右都缩小
    {
        min=left;
        max=right;
        for(int i=left;i<right;i++)
        {
            if(arr[i]>arr[max])
                max=i;
            if(arr[i]<arr[min])
                min=i;
        }
        if(max!=right)
            swap(&arr[max],&arr[right]);

        if(min==right)//最小值刚好在最右边
            min=max;

        if(min!=left)
            swap(&arr[min],&arr[left]);
    }
}
void swap(int *a,int *b)
{
    int t;
    t=*a;
    *a=*b;
    *b=t;
}

插入排序优化(二分法)

#include<stdio.h>
int binarysearch(int *arr,int start,int end,int k );
void insert_sort(int *arr,int len);
int main()
{
    int a[]={10,9,8,7,6,5,4,3,2,1};
    insert_sort(a,10);
    for(int i=0;i<10;i++)
        printf("%d ",a[i]);
}
int binarysearch(int *arr,int start,int end,int k )
{
    //算出来之前k大于的数的终点
    while(start<=end)
    {
        int middle=(start+end)/2;
        if(arr[middle]>k)
            end=middle-1;
        else 
            start=middle+1;
    }
    return start;
}
void insert_sort(int *arr,int len)
{
    int temp;
    int insert;
    for(int i=0;i<len-1;i++)
    {
        if(arr[i]>arr[i+1])
        {
            temp=arr[i+1];
            insert=binarysearch(arr,0,i+1,arr[i+1]);
            for(int j=i;j>=insert;j--)//将大数往后移动
                arr[j+1]=arr[j];
            arr[insert]=temp;//将小数放在比他小的数字之后
        }
    }
}

堆排序

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void MAX_HEADPIFY(int *arr,int i,int len);//建立最大堆
void swap(int *str1,int *arr2);//交换函数
void BULD_MAX_HEAP(int  *arr,int len);//建立堆
void HEADPSORT(int  *arr,int len);//排序
int main()
{
    int len;
    int  arr[]={12,11,13,10,9,8,7,6,5,4,3,2,1};
    HEADPSORT(arr-1,13);//因为堆排序找左右孩子的时候是2*i,2*i+1
    //如果不这样,计算i=0的时候会出错
    for(int i=0;i<13;i++)
        printf("%d ",arr[i]);
}
void swap(int *arr1,int *arr2)
{
    int  t;

    t=*arr1;
    *arr1=*arr2;
    *arr2=t;
}
void MAX_HEADPIFY(int *arr,int i,int len)//保证最大堆的性质
{
    int max=i;
    int left=2*i;
    int right=2*i+1;

    if(left<=len&&arr[left]>arr[max])//第二个不能使用str[i],因为左孩子可能比节点大
        max=left;                   //如果还是使用str[i]会让数据错误,切记!!!
    if(right<=len&&arr[right]>arr[max])
        max=right;
    if(max!=i)
    {
        swap(&arr[max],&arr[i]);
        MAX_HEADPIFY(arr,max,len);
    }
}

void BULD_MAX_HEAP(int  *arr,int len)//自底而上建堆
{
    int i;

    for(i=len/2;i>=1;i--)//i的len/2是树叶的个数
        MAX_HEADPIFY(arr,i,len);
}
void HEADPSORT(int *arr,int len)
{
    int i;

    BULD_MAX_HEAP(arr,len);//先建立堆
    for(i=len;i>=1;i--)
    {
        swap(&arr[1],&arr[i]);//取出最大值,保证之前str[1]永远是最大的
        len=len-1;
        MAX_HEADPIFY(arr,1,len);
    }
}

qsort使用

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int cmp(const  void *a, const void *b)
{
    return (*(int *)a)-(*(int *)b);//升序列
}
int main()
{
    int arr[]={10,9,8,7,6,5,4,3,2,1};
    qsort(arr,10,sizeof(int),cmp);
    for(int i=0;i<10;i++)
        printf("%d ",arr[i]);
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值