首页 > 技术文章 > 排序查找

hanbinggan 2015-02-24 13:26 原文

归并排序:(nlog(n)  小->大)

1.将数组分成两部分

2.将两部分分别排序

3.将排完序的两部分合为一部分

void merge_sort(int x,int y){
    if(y-x <= 1)
        return;
    int m = x + (y-x)/2;
    int p = x,q = m,i = x;
    merge_sort(x,m);
    merge_sort(m,y);
    while(p < m || q < y){
        if(q >= y || (p < m&&a[p] <= a[q]))
            t[i++] = a[p++];
        else
            t[i++] = a[q++];
    }
    for(int i = x;i < y;i++)
        a[i] = t[i];
    return;
}

求逆序对问题:(nlog(n),归并排序变种)

1.将问题分为两部分进行

2.分别对两部分的逆序对进行计算

3.对两部分右边比左边小的逆序对进行计算

4.相加

PS:由于之前归并排序是从小到大,在进行复制时将右边较小的复制到临时数组时,左边已剩下的个数就是比右边大的逆序数

int merge_sort(int x,int y){
    if(y-x <= 1)
        return 0;
    int m = x + (y-x)/2;
    int p = x,q = m,i = x;
    int L = merge_sort(x,m);
    int R = merge_sort(m,y);
    int cntt = 0;
    while(p < m || q < y){
        if(q >= y || (p < m&&a[p] <= a[q]))   
            t[i++] = a[p++];
        else{
            t[i++] = a[q++];  ///将右边复制到临时数组,而左边剩下没复制的就是比右边大的
            cntt += (m-p);
        }
    }
    for(int i = x;i < y;i++)
        a[i] = t[i];
    return (R+L+cntt);
}

快速排序:

1.在元素中找一个基准

2.将把基准大的数字放在基准右边,把比基准小的数字放在基准左边

3.对基准的左边和右边进行排序

void q_sort(int x,int y){
    if(x >= y)
        return;
    int k = a[x];
    int first = x;
    int last = y;
    while(first < last){
        while(first < last && a[last] >= k)
            last--;
        a[first] = a[last];
        while(first < last && a[first] <= k)
            first++;
        a[last] = a[first];
    }
    a[first] = k;
    q_sort(x,first-1);
    q_sort(first+1,y);
}

二分查找

int b_search(int x,int y,int v){
    int m;
    while(x < y){
        m = x + (y-x)/2;
        if(a[m] == v)
            return m;
        if(a[m] > v)
            y = m;
        else
            x = m+1;
    }
    return -1;
}

int _lower_bound(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;
}

int _upper_bound(int x,int y,int v){
    int m;
    while(x < y){
        m = x + (y-x)/2;
        if(a[m] <= v)
            x = m;
        else
            y = m+1;
    }
    return y;
}
View Code

 

推荐阅读