数据结构基础排序算法

从小到大排序
1、冒泡
每次从第一个元素开始与右边相邻元素两两比较,将较大元素右移。
需要移动n-1次。

void bubble(int a[], int n)
{
    int i;
    int tmp;
    int j;
    for(j=n-1; j>0; j--) // 需要n-1轮冒泡
    {
        for(i=0; i<j; i++) // 每轮冒泡将最大的移动到右侧
        {
            if(a[i] > a[i+1])
            {
                tmp = a[i];
                a[i] = a[i+1];
                a[i+1] = tmp;
            }
        }
    }
}

2、选择
每次选择0到i-1位置最大元素放到i位置。i从n-1到0变化。

void select(int a[], int n)
{
    int i;
    int j;
    int max, u;
    int tmp;
    for(i=n-1; i>0; i--) // 需要选择n-1次
    {
        max = a[0];
        u = 0;
        for(j=1; j<=i; j++) // 每次选择一个最大的放到右侧
        {
            if(max < a[j])
            {
                u = j;
                max = a[j];
            }
        }
        tmp = a[i];
        a[i] = a[u];
        a[u] = tmp;
    }
}

3、插入
每次把i位置元素插入到0到i-1合适位置。i从1到n-1。

void inserts(int a[], int n)
{
    int i;
    int j;
    int tmp;
    for(i=1; i<n; i++) // 需要插入n-1次
    {
        tmp = a[i];
        for(j=i-1; j>=0; j--) // 每次选择数插入到前面排好序的数组
        {
            if(tmp < a[j]) // 插入时找到合适位置,其它元素向后顺延
            {
                a[j+1] = a[j];
                if(j == 0) // 需要插在第一位时特殊判断
                    a[j] = tmp;
            }
            else
            {
                a[j+1] = tmp;
                break;
            }
        }
    }
}

4、快速
选取第一个为基准。将基准调整在中间位置,左边全是比基准小的。右边全是比基准大的。然后对左右分别递归快排。
调整方法:i指向基准,j指向数组最后一个元素。首先从右向左找到第一个比基准小的数,放到i位置,i++。然后从左往右找第一个比基准大的元素,放到j位置,j–。重复该过程,直到i>=j。将基准放到i位置。

void quick(int a[], int l, int r)
{
    if(l >= r) // 至少有两个元素
        return;

    int base = a[l]; // 选取第一个为基准
    int i = l;
    int j = r;

    while(i < j) // 至少有两个元素才需要快排
    {
        while(i < j &&a[j] >= base) // 从右向左找第一个比base小的
            j--;
        if(i < j) // 如果找到了
        {
            a[i] = a[j];
            i++;
        }
        while(i < j && a[i] <= base) // 从左向右找第一个比base大的
            i++;
        if(i < j) // 如果找到了
        {
            a[j] = a[i];
            j--;
        }
    }
    a[i] = base;
    quick(a, l, i-1);
    quick(a, i+1, r);
}

5、归并
将数组切分成均等的两份(允许前面数组比后面数组多一个元素),分别递归这两部分,然后将这两部分合并成一部分。
合并方法:
对两部分的每个元素两两比较,较小者优先放到合并后的数组中。两部分长度不一致时,较长数组剩下元素依次放入合并后数组即可。

void merges(int a[], int l, int r)
{
    if(l >= r)
        return; // 至少有两个元素

    int mid = (l + r) / 2; // 拆分进行归并排序两个子数组
    merges(a, l, mid);
    merges(a, mid+1, r);

    // 合并两个子数组为新数组,再将新数组复制回去
    int t[r-l+1];
    int k = 0;
    int i = l;
    int j = mid+1;
    while(i <= mid && j <= r)
    {
        if(a[i] <= a[j])
        {
            t[k] = a[i];
            i++;
        }
        else
        {
            t[k] = a[j];
            j++;
        }
        k++;
    }
    while(i <= mid)
    {
        t[k] = a[i];
        i++;
        k++;
    }
    while(j <= r)
    {
        t[k] = a[j];
        j++;
        k++;
    }
    for(i=0; i<k; i++)
    {
        a[i+l] = t[i];
    }
}

测试

#include <stdio.h>

void outputa(int a[], int l, int r)
{
    int i;
    for(i=l; i<r; i++)
    {
        printf("%d ", a[i]);
    }
    printf("%d\n", a[i]);
}

int main()
{
    int a1[7] = {23, 14, 37, 48, 5, 1, 11};
    bubble(a1);
    printf("bubble sort...\n");
    outputa(a1, 0, 6);
    int a2[7] = {23, 14, 37, 48, 5, 1, 11};
    select(a2);
    printf("select sort...\n");
    outputa(a2, 0, 6);
    int a3[7] = {23, 14, 37, 48, 5, 1, 11};
    inserts(a3);
    printf("insert sort...\n");
    outputa(a3, 0, 6);
    int a4[7] = {23, 14, 37, 48, 5, 1, 11};
    quick(a4, 0, 6);
    printf("quick sort...\n");
    outputa(a4, 0, 6);
    int a5[7] = {23, 14, 37, 48, 5, 1, 11};
    merges(a5, 0 ,6);
    printf("merge sort...\n");
    outputa(a5, 0, 6);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值