排序總結


基於比較的排序

冒泡排序

元素相鄰位置互相交換


選擇排序

每次查找爲排過序的元素中最小的位置


插入排序

把當前位置的元素插入到已經排過序的元素中去,使其有序


希爾排序

分段進行插入排序


快速排序

分治處理 把每個元素放進她應該在的位置上

應用

靜態選擇第k大


歸併排序

分治處理並進行合併

應用

求逆序數點擊打開poj題目鏈接

#include<cstdio>
#define N 600050
using namespace std;
long long p[N],a[N];
long long sum=0;
void merge(int first,int  last)
{
    int mid=(first+last)/2;

    int i1=0,i2=first,i3=mid+1;

    while(i2<=mid&&i3<=last)
    {
        if(a[i2]>a[i3])
        {
            p[i1++]=a[i3++];
            sum+=mid+1-i2;
        }
        else p[i1++]=a[i2++];
    }
    while(i2<=mid)p[i1++]=a[i2++];
    while(i3<=last)p[i1++]=a[i3++];

    i1=first;i2=0;
    while(i2<last-first+1)a[i1++]=p[i2++];
}
void merge_sort(int first,int  last)
{
    int mid;
    if(first<last)
    {
        mid=(first+last)/2;
        merge_sort(first,mid);
        merge_sort(mid+1,last);
        merge(first,last);
    }
}

int main()
{
    int n;
    while(scanf("%d",&n),n)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%lld",&a[i]);
            p[i]=a[i];
        }
        sum=0;
        merge_sort(0,n-1);

        printf("%lld\n",sum);

    }
    return 0;
}


堆排序

用堆維護,進行選擇排序

應用

問題描述

給定各包含n個數兩個數列A、B,分別從A和B中任意取一個數相加得到和,這樣會有n^2種結果(包括重複的),求n^2個結果中前n個最小的和。

點擊打開哈理工oj題目鏈接

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1000010
using namespace std;
int f[N],s[N], val1[N], val2[N],ans[N], hs,n;
void keep( int rt ) {
    int cur = rt;
    int l = rt<<1;
    int r=l+1;
    if( l<=hs && val1[ f[l] ]+ val2[ s[l] ]< val1[ f[cur] ]+ val2[ s[cur] ] ) cur=l;
    if( r<=hs && val1[ f[r] ]+ val2[ s[r] ] < val1[ f[cur] ]+ val2[ s[cur] ] ) cur=r;
    if( cur != rt ) {
        swap(f[cur],f[rt]);
        swap(s[cur],s[rt]);
        keep(cur);
    }
}
int work( int n )
{
    hs=n;
    for( int i = 0; i < n; i ++ ){
        ans[i]= val1[ f[1] ]+val2[ s[1] ];
        if( f[1] <n ) f[1]++;
        else {
            f[1]=f[hs];
            s[1]=s[hs--];
        }
        keep(1);
    }
}
int main() {
    while( ~scanf("%d",&n) ) {
        for( int i = 1; i <= n; i ++ )
            scanf("%d",&val1[i]);
        for( int i = 1; i <= n; i ++ )
            scanf("%d",&val2[i]);
        sort(val1+1,val1+n+1);
        sort(val2+1,val2+n+1);
        for( int i = 1; i <= n; i ++ )
            f[s[i]=i]=1;
        work(n);
        printf("%d",ans[0]);
        for( int i = 1; i < n; i ++ )
			printf(" %d",ans[i]);
        printf("\n");
    }
    return 0;
}


基於索引的排序

計數排序

根據數據的類型進行映射索引,然後進行索引查找排序


基數排序

把數據進行分割後進行排序


桶排序

根據數據建立映射到某區域裏,然後進行分桶處理,同一桶內進行插入排序


外部排序

一般是對相對於較大文件進行排序,文件比較大,內存不足。

一般分爲兩個過程:

1、把大文件分成多個子文件,並一一排序單個子文件。

2、合併所有的子文件


主要是在合併的過程中,由於內存不足,所以只能邊合併邊寫到文件。這個過程中可以用堆、勝者樹或敗者樹進行維護


網絡排序

是針對多處理機並行處理的排序


字符串排序

對於多個字符串,可以先用字典樹存儲,然後進行先序遍歷即可完成排序


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章