考研——排序算法整理6/10个(预计9.30全部整理完)

1. 快速排序

题目链接

// 以数组的中间元素为枢轴来划分
void quick_sort(int a[], int l, int r)
{
    if (l >= r) return;
    int i = l - 1, j = r + 1;
    int x = a[l + r >> 1];
    while (i < j)
    {
        do i ++; while(a[i] < x);
        do j --; while(a[j] > x);
        if (i < j) swap(a[i], a[j]);
    }
    quick_sort(a, l, j);
    quick_sort(a, j + 1, r);
}
// 以数组的第一个元素为枢轴来划分
void quick_sort(int a[], int l, int r)
{
    if (l >= r) return;
    int x = a[l];
    int i = l - 1, j = r + 1;
    while (i < j)
    {
        do i ++; while(a[i] < x);
        do j --; while(a[j] > x);
        if (i < j) swap(a[i], a[j]);
    }
    quick_sort(a, l, j);
    quick_sort(a, j + 1, r);
}

2. 归并排序

题目链接

int tmp[N];
void merge_sort(int a[], int l, int r)
{
    if (l >= r) return;
    int mid = l + r >> 1;
    merge_sort(a, l, mid);
    merge_sort(a, mid + 1, r);
    
    int k = 0;
    int i = l, j = mid + 1;
    while (i <= mid && j <= r)
    {
        if (a[i] < a[j]) tmp[k ++] = a[i ++];
        else tmp[k ++] = a[j ++];
    }
    while (i <= mid) tmp[k ++] = a[i ++];
    while (j <= r) tmp[k ++] = a[j ++];
    for (int i = l, j = 0; i <= r; i ++, j ++) a[i] = tmp[j];
}

3. 堆排序

题目链接

// !!!特殊:堆排序中数组a下标从1开始
// 假设数组a为全局变量,不然没办法运行…
void down(int u, int cnt)    // 结点不断下坠
{
    int t = u;
    if (2 * u <= cnt && a[2 * u] > a[t]) t = 2 * u;
    if (2 * u + 1 <= cnt && a[2 * u + 1] > a[t]) t = 2 * u + 1;
    if (t != u)
    {
        swap(a[t], a[u]);
        down(t, cnt);
    }
}
void heap_sort(int a[], int n)
{
    // 大根堆:从小到大,得到的是升序序列;
    // 小根堆:小大到小,得到的是降序序列;
    // 建立大根堆的过程
    for (int i = n / 2; i >= 1; i --) down(i, n);
    // 堆排序的过程
    int cnt = n;    // cnt记录需要排序的二叉树中的结点个数
    for (int i = n; i > 1; i --)
    {
        // 我真吐了,调试半天,没发现是a[i]写成了别的
        swap(a[i], a[1]);
        cnt --;
        down(1, cnt);
    }
}

4. 直接插入排序

void insert_sort(int a[], int n)
{
    for (int i = 1; i < n; i ++)
    {
        int x = a[i]; // 待插入元素,相当于“哨兵”
        int j;
        for (j = i - 1; j >= 0; j --)
        {
            if (a[j] > x) a[j + 1] = a[j];
            else break;
        }
        a[j + 1] = x;
    }
}

5. 折半插入排序

void binary_insert(int a[], int n)
{
    for (int i = 1; i < n; i ++)
    {
        int x = a[i]; // 待插入元素
        // l指向从左往右第一个大于x的元素,即插入位置
        int l = 0, r = i - 1;
        while (l <= r)
        {
            int mid = l + r >> 1;
            if (a[mid] > x) r = mid - 1;
            else l = mid + 1;
        }
        for (int j = i - 1; j >= l; j --)
            a[j + 1] = a[j];
        a[l] = x;
    }
}

6. 简单选择排序

void select_sort(int a[], int n)
{
    for(int i = 0; i < n; i++)
    {
        for(int j = i + 1; j < n; j++)
            if(a[j] < a[i]) swap(a[i], a[j]);
    }
}

7. 冒泡排序

8. 基数排序

9. 按名次排序

10. 箱子排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值