ACM - 8.2 再谈排序与检索

8.2.1 归并排序

归并排序的过程本身是线性的,但是需要线性的辅助空间。

c#include <stdio.h>
#include <string.h>
#include <iostream>

using namespace std;

const int maxn =1000;
const int INF = 0x3f3f3f3f;

int a[maxn];
int t[maxn];

void merge_sort(int *a, int x, int y, int *t)
{
    if(y-x > 1)
    {
        // 取中
        int m = x + (y-x)/2;
        int p = x, q = m, i = x;
        // 两部分分别排序
        merge_sort(a, x, m, t);
        merge_sort(a, m, y, t);

        while(p < m || q < y)
        {
            if(q >= y || (p < m && a[p] <= a[q])) t[i++] = a[p++];
            else t[i++] = a[q++];
        }

        for(i = x; i < y; i++) a[i] = t[i];
    }
}


int main()
{
    int a[] = {1 , 6, 4 , 2, 1 ,9, 10, 0};
    merge_sort(a, 0, 8, t);
    for(int i = 0; i < 8; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;

    return 0;
}
  • 逆序对数
cint cnt = 0;
void merge_sort(int *a, int x, int y, int *t)
{
    if(y-x > 1)
    {
        int m = x + (y-x)/2;
        int p = x, q = m, i = x;
        while(p < m || q < y)
        {
            if(q >= y || (p < m && a[p] > a[q])) t[i++] = a[p++];
            else 
            {
                t[i++] = a[q++];
                cnt += m - p;
            }
        }

        for(int i = x ;i < y ;i ++) a[i] = t[i];
    }
}

8.2.2 快速排序

整体排序之后部分排序。此处并非随机划分。

cvoid quicksort(int *a, int l, int r)
{
    if(l < r)
    {
        int i = l, j = r, x = a[l];
        while(i < j)
        {
            while(i < j && a[j] >= x) j--;
            if(i < j) a[i++] = a[j];
            while(i < j && a[i] < x) i++;
            if(i < j) a[j--] = a[i];
        }
        a[i] = x;
        quicksort(a, l, i-1);
        quicksort(a, i+1, r);
    }
}
  • 第k小数
c#include <stdio.h>
#include <string.h>
#include <iostream>

using namespace std;

const int maxn =1000;
const int INF = 0x3f3f3f3f;

int a[maxn];
int t[maxn];


int cnt = 0;
int k;

int quicksortFind(int *a, int l, int r)
{
    if(l < r)
    {
        int i = l, j = r, x = a[l];
        while(i < j)
        {
            while(i < j && a[j] >= x)
                j--;
            if(i < j)
                a[i++] = a[j];
            while(i < j && a[i] <= x)
                i++;
            if(i < j)
                a[j--] = a[i];
        }
        a[i] = x;
        if(l <= k && i-1 >= k)
            return quicksortFind(a, l, i-1);
        else if(i+1 <= k && k <= r)
            return quicksortFind(a, i+1, r);
        else
            return x;
    }
    return a[l];
}


#define printArray(a, len) for(int i = 0 ;i < len; i++) cout << a[i] << " "; cout << endl;

int main()
{
    int a[] = {1 , 6, 4 , 2, 1 ,9, 10, 0};
    k = 4;
    int temp = quicksortFind(a, 0, 7);
    printArray(a, 8);
    printf("%d\n", temp);
    return 0;
}

8.2.3 二分查找

cint bsearch(int *a, int x, int y, int v)
{
    int m;
    while(x < y)
    {
        m = x + (y-x)/2;
        if(a[m] == v) return m;
        else if(a[m] > v) y = m;
        else x = m+1;
    }
    // 没找到
    return -1;
}
  • 二分查找求下界

不再直接返回,在STL函数中包含这个算法

  • lower_bound(a, a+n, v)
  • upper_bound(a, a+n, b)
cint bsearch(int *a, int x, int y, int v)
{
    int m;
    while(x < y)
    {
        m = x + (y-x)/2;
        if(a[m] >= v) y = m;
        else x = m+1;
    }
    // 没找到
    return x;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值