基於比較的排序
冒泡排序
元素相鄰位置互相交換
選擇排序
每次查找爲排過序的元素中最小的位置
插入排序
把當前位置的元素插入到已經排過序的元素中去,使其有序
希爾排序
分段進行插入排序
快速排序
分治處理 把每個元素放進她應該在的位置上
應用
靜態選擇第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個最小的和。
#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、合併所有的子文件
主要是在合併的過程中,由於內存不足,所以只能邊合併邊寫到文件。這個過程中可以用堆、勝者樹或敗者樹進行維護
網絡排序
是針對多處理機並行處理的排序
字符串排序
對於多個字符串,可以先用字典樹存儲,然後進行先序遍歷即可完成排序