6种排序模板

版权声明:转载时 别忘了注明出处 https://blog.csdn.net/ZCY19990813/article/details/83089372

看几个动画演示  http://atool.org/sort.php     http://jsdo.it/norahiko/oxIy/fullscreen

一:冒泡排序  O(n*n)

冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
int main()
{
    int a[1000],i,j,n,t;
    cin>>n;
    for(i=0;i<n;i++)
       cin>>a[i];
    for(i=0;i<n-1;i++)
    {
        for(j=0;j<n-i-1;j++)
        {
            if(a[j]>=a[j+1])
            {
                t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
            }
        }
    }
    for(i=0;i<n;i++)
        cout<<a[i]<<" ";
    return 0;
}

二:选择排序 O(n*n)

选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
int main()
{
    int a[1000],i,j,n,t,p;
    cin>>n;
    for(i=0;i<n;i++)
       cin>>a[i];
    for(i=0;i<n-1;i++)
    {
        p=i;
        for(j=i+1;j<n;j++)
        {
            if(a[p]>=a[j])
            {
                p=j;
            }
        }
        t=a[i];
        a[i]=a[p];
        a[p]=t;
    }
    for(i=0;i<n;i++)
        cout<<a[i]<<" ";
    return 0;
}

三:插入排序   O(nlogn)

n插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
typedef long long ll;
ll a[10100];
int main()
{
    ll n,i,j,c,p;
    cin>>n;
    for(i=0;i<n;i++)
        cin>>a[i];
    for(i=1;i<n;i++)
    {
        p=i-1;
        c=a[i];
        while(p>=0&&a[p]>c)
        {
            a[p+1]=a[p];
            p--;
        }
        a[p+1]=c;
    }
    for(i=0;i<n;i++)
        cout<<a[i]<<" ";
    return 0;
}

四:归并排序  O(nlogn)

合并操作(merge),是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

看个例题纯模板

对每一组输入,输出该序列变成有序所需要交换的最少的次数。

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
typedef long long ll;
ll a[500001],b[500001];
ll cnt;
void merge_bing(ll frist,ll mid,ll last)
{
    ll midd=mid+1;
    ll d=0;
    ll f=frist;
    while(frist<=mid&&midd<=last)
    {
        if (a[frist]<=a[midd])
            b[d++]=a[frist++];
        else
        {
            cnt+=mid-frist+1;
            b[d++]=a[midd++];
        }
    }
    while(frist<=mid)
        b[d++]=a[frist++];
    while(midd<=last)
        b[d++]=a[midd++];
    for(ll i=0;i<d;i++)
        a[f++]=b[i];
}
void mergesort(ll frist,ll last)
{
    ll mid=0;
    if (frist<last)
    {
        mid=(frist+last)/2;
        mergesort(frist,mid);
        mergesort(mid+1,last);
        merge_bing(frist,mid,last);
    }
}
int main()
{
    int n;
    while(cin>>n)
    {
        if(n==0)
            break;
        ll i,j;
        for(i=0;i<n;i++)
            cin>>a[i];
        cnt=0;
        mergesort(0,n-1);
        cout<<cnt<<endl;
    }
    return 0;
}

五:快速排序  O(nlogn)

快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

就是qsort 但是现在一般用sort直接调用函数就好

六:堆排序  O(nlogn)

n堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

void heap_sort( int arr[], int len )
{
    int i;
    /* 初始化,i从最后一个父结点开始调整 */
    for ( i = len / 2 - 1; i >= 0; i-- )
        max_heapify( arr, i, len - 1 );
    /* 先将第一个元素和已排好元素前一位做交换,再重新调整,直到排序完毕 */
    for ( i = len - 1; i > 0; i-- )
    {
        swap( &arr[0], &arr[i] );
        max_heapify( arr, 0, i - 1 );
    }
}
void max_heapify( int arr[], int start, int end )
{
    /* 建立父结点指标和子结点指标 */
    int dad = start;
    int son = dad * 2 + 1;
    while ( son <= end )                                            /* 若子结点在指定范围内才做比较 */
    {
        if ( son + 1 <= end && arr[son] < arr[son + 1] )  /* 先比较两个子结点大小,选择最大的 */
            son++;
        if ( arr[dad] > arr[son] )         /* 如果父结点大于子结点表示调整完毕,直接跳出函数 */
            return;
        else {                                                 /* 否则交换父子内容再继续子结点和孙结点比较 */
            swap( &arr[dad], &arr[son] );
            dad = son;
            son = dad * 2 + 1;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/ZCY19990813/article/details/83089372