十种排序算法

1.常见算法分类
十种常见排序算法一般分为以下几种:
(1)非线性时间比较类排序:交换类排序(快速排序和冒泡排序)、插入类排序(简单插入排序和希尔排序)、选择类排序(简单选择排序和堆排序)、归并排序(二路归并排序和多路归并排序);

(2)线性时间非比较类排序:计数排序、基数排序和桶排序。

总结:
(1)在比较类排序中,归并排序号称最快,其次是快速排序和堆排序,两者不相伯仲,但是有一点需要注意,数据初始排序状态对堆排序不会产生太大的影响,而快速排序却恰恰相反。

(2)线性时间非比较类排序一般要优于非线性时间比较类排序,但前者对待排序元素的要求较为严格,比如计数排序要求待排序数的最大值不能太大,桶排序要求元素按照hash分桶后桶内元素的数量要均匀。线性时间非比较类排序的典型特点是以空间换时间。
注:本博文的示例代码均已递增排序为目的。

2.1交换类排序
2.1.1冒泡类排序

void BubbleSort(int *arr,int size)
{
    int i,j;
    int flag,tmp;
    for(i = 0 ;i < size; i++)
    {
        flag = 1;
        for(j = 0 ; j < size - i - 1;j++)
        {
            if(arr[j] > arr[j + 1])
            {
                flag = 0;
                tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
        if(1 == flag)
        {
            break;
        }
    }
}

2.1.2快速排序

int Departition(int *arr,int left ,int right)
{
    int tmp = arr[left];
    while(left < right)
    {
        while(left < right && tmp < arr[right])
            right--;
        if(left < right)
            arr[left++] = arr[right];
        while(left < right && tmp > arr[left])
            left++;
        if(left < right)
            arr[right--] = arr[left];
    }
    arr[left] = tmp;
    return left;
}

void DoQuickSort(int *arr,int left,int right)
{
    int t;
    if(left < right)
    {
        t = Departition(arr,left,right);
        DoQuickSort(arr,0,t - 1);
        DoQuickSort(arr,t + 1,right);
    }
}
void QuickSort(int *arr,int size)
{
    DoQuickSort(arr,0,size -1);
}

2.2 插入类排序
2.2.1直接插入

void InsertSort(int *arr,int size)
{
    int i,j,tmp;
    for(i = 1 ; i < size; i++)
    {
        tmp = arr[i];
        j = i;
        while(j >= 1 && tmp < arr[j -1])
        {
            arr[j] =  arr[j -1];
            j--;
        }
        arr[j] = tmp;
    }
}

2.2.2 shell排序

void ShellSort(int *arr,int size,int d)
{
    int i,j,k,tmp;
    for(i = d;i > 0;i = i/2)
    {
        for(j = 0 ;j < size ; j += i)
        {
            tmp = arr[j];
            k = j;
            while(k >= i && tmp < arr[k - i])
            {
                arr[k] = arr[k - i];
                k -= i;
            }
            arr[k] = tmp;
        }
    }
}

2.3选择类排序
2.3.1直接选择类排序

  void SelectSort(int *arr,int size)
    {
        int i,j,min;
        int tmp;
        for(i = 0 ;i  < size; i++)
        {
            min = i;
            for(j = i + 1; j < size ; j++)
            {
                 if(arr[min] > arr[j])
                    min = j;
            }
            if(i != min)
            {
                tmp = arr[i];
                arr[i] = arr[min];
                arr[min] = tmp;
            }
        }
    }

2.3.2 堆排序

void AdjustHeap(int *arr,int node,int size)
{
    int child = 2*node + 1;
    int tmp = arr[node];
    while(child < size)
    {
        if(child + 1 < size && arr[child] < arr[child + 1])
        {
            child++;
        }
        if(tmp < arr[child])
        {
            arr[node] = arr[child];
            node = child;
            arr[node] = tmp;
            child = 2*child + 1;
        }
        else
        {
            break;
        }
    }
}
void HeapSort(int *arr,int size)
{
    int i,j,tmp;
    for(i = (size -1)/2 ; i >= 0 ; i--)
        AdjustHeap(arr,i,size);

    /*  printf("after create heap\n");
    for(i = 0 ; i < MAX ; i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
    */
    for(i = 1 ;i < size; i++)
    {
        tmp = arr[0];
        arr[0] = arr[size - i];
        arr[size - i] = tmp;
        AdjustHeap(arr,0,size -i);
    }

}

2.4归并排序

void Merge(int *src,int *tmp,int begin,int mid,int end)
{
    int i = begin ,j = mid + 1,k = begin;
    while( i != mid + 1 && j != end + 1)
    {
        if(src[i] > src[j])
        {
            tmp[k++] = src[j++];
        }
        else
        {
            tmp[k++] = src[i++];
        }
    }
    while(i != mid + 1)
    {
        tmp[k++] = src[i++];
    }
    while(j != end + 1)
    {
         tmp[k++] = src[j++];
    }
    for(i = begin ; i <= end; i++)
    {
        src[i] = tmp[i];
    }
}

void MergeSort(int *src,int *tmp,int begin,int end)
{
    int mid;
    if(begin < end)
    {
        mid = (begin + end)/2;
        MergeSort(src,tmp,begin,mid);
        MergeSort(src,tmp,mid+1,end);
        Merge(src,tmp,begin,mid,end);
    }
}

以上是非线性时间比较类排序, 线性时间非比较类排序常见方法如下。
2.5计数排序

void CountSort(int *arr,int size)
{
    int i,j,count,max;
    int *tmp;
    max = arr[0];
    for(i = 1;i < size; i++)
    {
        if(max < arr[i])
        {
            max = arr[i];
        }
    }
    tmp = (int *)malloc(sizeof(int)*(max + 1));
    if(NULL == tmp)
    {
        printf("malloc failure\n");
        return;
    }
    memset(tmp,0,sizeof(int)*(max + 1));
    for(i = 0 ; i < size ; i++)
    {
        tmp[arr[i]]++;
    }

    count = 0;
    for(i = 0;i <= max; i++)
    {
       j = 0;
       while(j < tmp[i])
       {
           arr[count++] = i;
           j++;
       }
    }
    free(tmp);
    tmp = NULL;
}

2.6 基数排序

int GetDigitalPos(int num,int pos)
{
    int i,mask = 1;
    for(i = 0;i < pos -1; i++)
    {
        mask *= 10;
    }
    return (num/mask)%10;
}

void DistributionSort(int *arr,int size)
{
    int *buff[10] = {NULL}; /* 0 ~ 9 */
    int i,j;
    for(i = 0 ;i < 10; i++)
    {
        buff[i] = (int *)malloc(sizeof(int)*(size + 1));
        if(NULL == buff[i])
        {
            for(j = 0; j < i; j++)
            {
                free(buff[j]);
                buff[j] = NULL;
                return;
            }
        }
        buff[i][0] = 0; /* 保存统计数目 */
    }

    int index,count,k;
    for(i = 1; i < MAX_BIT; i++)
    {
        /* 装入桶中 */
        for(j = 0; j < size; j++)
        {
            index = GetDigitalPos(arr[j],i);
            buff[index][buff[index][0]+1] = arr[j];
            buff[index][0]++;
        }

        /* 将桶中数据装回原空间 */
        count = 0;
        for(j = 0; j < 10; j++)
        {
           for(k = 0; k < buff[j][0]; k++)
           {
               arr[count++] = buff[j][k + 1];
           }
           buff[j][0] = 0;
        }
    }

    /* 释放桶空间 */
     for(i = 0 ;i < 10; i++)
     {
         free(buff[i]);
         buff[i] = NULL;
     }
}

2.7 桶排序

struct bucket
{
    int num;
    int val;
    struct bucket *next;
};
void Release(struct bucket **root,int num)
{
    int i;
    struct bucket *node,*next;
    struct bucket **tmp = root;

    if(NULL == tmp)
    {
        return;
    }

    for(i = 0; i < num; i++)
    {
        if(tmp[i])
        {
            node = tmp[i];
            while(node)
            {
                next = node ->next;
                free(node);
                node = next;
            }
            tmp[i] = NULL;
        }
    }

    if(tmp)
    {
        free(tmp);
        tmp = NULL;
    }
}
void BucketSort(int *arr,int size)
{
    int i,index;
    struct bucket *p,*node;
    struct bucket **root = (struct bucket **)malloc(sizeof( struct bucket *)*BUCKET_NUM);
    if(NULL == root)
    {
        printf("malloc failure \n");
        return;
    }

    for(i = 0; i < BUCKET_NUM; i++)/* BUCKET_NUM 桶数目 */
    {
        root[i] = (struct bucket *)malloc(sizeof(struct bucket));
        if(NULL == root[i])
        {
           Release(root,BUCKET_NUM);
           return;
        }
        root[i] ->num = 0;
        root[i] ->next = NULL;
        root[i] ->val = 0;
    }

    /* 将数据装入桶中 */
    for(i = 0; i < size; i++)
    {
        index = arr[i]/BUCKET_NUM;
        p = root[index];
        node = (struct bucket *)malloc(sizeof(struct bucket));
        if(NULL == node)
        {
            Release(root,BUCKET_NUM);
            return;
        }
        node ->val = arr[i];
        node ->next = NULL;
        if(p ->num == 0)
        {
            p ->next = node;
        }
        else
        {
            while(p ->next && p ->next ->val <= arr[i])
                p = p ->next;
            node ->next = p ->next;
            p ->next = node;
        }
        (p ->num)++;
    }

    /* 打印 */
    for(i = 0; i < BUCKET_NUM; i++)
    {
        p = root[i] ->next;
        while(p != NULL)
        {
            printf("%d ",p ->val);
            p = p ->next;
        }
    }
    printf("\n");
    Release(root,BUCKET_NUM);
}

转:https://blog.youkuaiyun.com/coolwriter/article/details/78732728

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值