排序总结


基于比较的排序

冒泡排序

元素相邻位置互相交换


选择排序

每次查找为排过序的元素中最小的位置


插入排序

把当前位置的元素插入到已经排过序的元素中去,使其有序


希尔排序

分段进行插入排序


快速排序

分治处理 把每个元素放进她应该在的位置上

应用

静态选择第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、合并所有的子文件


主要是在合并的过程中,由于内存不足,所以只能边合并边写到文件。这个过程中可以用堆、胜者树或败者树进行维护


网络排序

是针对多处理机并行处理的排序


字符串排序

对于多个字符串,可以先用字典树存储,然后进行先序遍历即可完成排序


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值