码迷,mamicode.com
首页 > 编程语言 > 详细

排序算法

时间:2016-06-14 23:52:29      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:

算法第四版学习笔记 图片来自http://algs4.cs.princeton.edu/home/

 

1.选择排序

从数组中找到最小的元素,将它和第一个元素交换,然后从剩下的元素中找到最小的元素并与第二个元素交换..如此重复

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;

int main()
{
    int temp=0;
    int a[10];
    cout<<"输入"<<endl;
    for(int i=0;i<10;i++)
    {
        cin>>a[i];
    }
    for(int i=0;i<10;i++)
    {
        for(int j=i+1;j<10;j++)
        {
            if(a[i]>a[j])
            {
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
        }
    }
    for(int i=0;i<10;i++)
        cout<<a[i]<<" ";
}

选择排序的运行时间和输入无关,且数据移动是最少的。

2.插入排序

将当前元素和之前的元素比较,若小于前一个元素则交换

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;

int main()
{
    int temp=0;
    int a[10];
    cout<<"输入"<<endl;
    for(int i=0;i<10;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<10;i++)
    {
        for(int j=i;j>0 && (a[j]<a[j-1]);j--)
        {
            temp=a[j-1];
            a[j-1]=a[j];
            a[j]=temp;
        }
    }
    for(int i=0;i<10;i++)
        cout<<a[i]<<" ";
}

适用于:

  1.数组中每个元素离它最终的位置不远

  2.一个有序大数组接一个小数组

  3.数组中只有几个元素的位置不正确

3.希尔排序

使数组中任意间隔为h的元素都是有序的,对每个子数组进行插入排序。

技术分享

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;

int main()
{
    int temp=0;
    int a[20];
    cout<<"输入"<<endl;
    for(int i=0;i<20;i++)
    {
        cin>>a[i];
    }
    int h=1;
    while(h<20/3) h=3*h+1;
    while(h>=1)
    {
        for(int i=h;i<20;i++)
        {
            for(int j=i;j>=h && a[j]<a[j-h];j -= h)
            {
                temp=a[j];
                a[j]=a[j-h];
                a[j-h]=temp;
            }
        }
        h = h/3;
    }
    for(int i=0;i<20;i++)
        cout<<a[i]<<" ";
}

4.归并排序

归并排序分为自顶向下的归并排序和自底向上的归并排序。其思想主要是先递归的将数组分成对半的两个序列,分别进行排序然后将结果归并。

  1.自顶向下的归并排序

  

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
void merge_(int a[],int lo,int mid,int hi)
{
    int aux[20];
    int i=lo,j=mid+1;
    for(int k=lo;k<=hi;k++)
        {
            aux[k]=a[k];
        }
    for(int k=lo;k<=hi;k++)
    {
        if(i>mid) a[k]=aux[j++];
        else if(j>hi) a[k]=aux[i++];
        else if(aux[j]<aux[i]) a[k]=aux[j++];  //这里比较不能使用a[i]而要用aux,因为a数组在比较中已经改变
        else a[k]=aux[i++];
    }
}
void sort_(int a[],int lo,int hi)
{
    if(hi<=lo) return;
    int mid=lo + (hi-lo)/2;
    sort_(a,lo,mid);    //将左半边排序
    sort_(a,mid+1,hi);  //将右半边排序
    merge_(a,lo,mid,hi);
}
int main()
{
    int temp=0;
    int a[20];
    cout<<"输入"<<endl;
    for(int i=0;i<20;i++)
    {
        cin>>a[i];
    }
    sort_(a,0,19);
    for(int i=0;i<20;i++)
        cout<<a[i]<<" ";
}

   2.自底向上的归并排序

#include <iostream>
#include <algorithm>
using namespace std;
void merge_(int a[],int lo,int mid,int hi)
{
    int aux[20];
    int i=lo,j=mid+1;
    for(int k=lo;k<=hi;k++)
        {
            aux[k]=a[k];
        }
    for(int k=lo;k<=hi;k++)
    {
        if(i>mid) a[k]=aux[j++];
        else if(j>hi) a[k]=aux[i++];
        else if(aux[j]<aux[i]) a[k]=aux[j++];  //这里比较不能使用a[i]而要用aux,因为a数组在比较中已经改变
        else a[k]=aux[i++];
    }
}
void sort_(int a[])
{
    int n=20;
    for(int sz=1;sz<n;sz += sz)
    {
        for(int lo=0;lo<n-sz;lo += sz+sz)
            merge_(a,lo,lo+sz-1,min(lo+sz+sz-1,n-1));
    }
}
int main()
{
    int temp=0;
    int a[20];
    cout<<"输入"<<endl;
    for(int i=0;i<20;i++)
    {
        cin>>a[i];
    }
    sort_(a);
    for(int i=0;i<20;i++)
        cout<<a[i]<<" ";
    return 0;
}

5.快速排序

将数组分成两个子数组独立排序,每次选定一个切分元素,从数组左端扫描数组直到找到一个大于等于它的元素,再从右往左扫描数组直到找到一个小于等于它的数组,交换两个元素。当两指针相遇,将切分元素和左数组最右端的元素交换。

#include <iostream>

using namespace std;
void exch(int a[],int i,int j)
{
    int temp = 0;
    temp = a[i];
    a[i]=a[j];
    a[j] = temp;
}
int partition_(int a[],int lo,int hi)
{
    int i=lo,j=hi+1;
    int v=a[lo];
    while(true)
    {
        while(a[++i] < v) if(i == hi) break;
        while(v < a[--j]) if(j == lo) break;
        if (i >= j) break;
        exch(a,i,j);
    }
    exch(a,lo,j);
    return j;
}
void sort_(int a[],int lo,int hi)
{
    if(hi <= lo) return;
    int j = partition_(a,lo,hi);
    sort_(a,lo,j-1);
    sort_(a,j+1,hi);
}
int main()
{
    int temp=0;
    int a[20];
    cout<<"输入"<<endl;
    for(int i=0;i<20;i++)
    {
        cin>>a[i];
    }
    sort_(a,0,19);
    for(int i=0;i<20;i++)
        cout<<a[i]<<" ";
    return 0;
}

  快速排序改进:三项切分快速排序

  将数组分成小于v 等于v和大于v三部分。维护一个指针lt使得a[lo..lt-1]中的元素都小于v,一个指针gt使得a[gt+1..hi]中的元素都大于v,一个指针i使得a[lt..i-1]中的元素都等于v,a[i..gt]中的元素还未确定。

  技术分享

#include <iostream>

using namespace std;
void exch(int a[],int i,int j)
{
    int temp = 0;
    temp = a[i];
    a[i]=a[j];
    a[j] = temp;
}
int partition_(int a[],int lo,int hi)
{
    int i=lo,j=hi+1;
    int v=a[lo];
    while(true)
    {
        while(a[++i] < v) if(i == hi) break;
        while(v < a[--j]) if(j == lo) break;
        if (i >= j) break;
        exch(a,i,j);
    }
    exch(a,lo,j);
    return j;
}
void sort_(int a[],int lo,int hi)
{
    if(hi <= lo) return;
    int lt=lo,i=lo+1,gt=hi;
    int v=a[lo];
    while(i<=gt)
    {
        if(a[i]<v) exch(a,i++,lt++);
        else if(a[i] == v) i++;
        else exch(a,i,gt--);
    }
    sort_(a,lo,lt-1);
    sort_(a,gt+1,hi);
}
int main()
{
    int temp=0;
    int a[20];
    cout<<"输入"<<endl;
    for(int i=0;i<20;i++)
    {
        cin>>a[i];
    }
    sort_(a,0,19);
    for(int i=0;i<20;i++)
        cout<<a[i]<<" ";
    return 0;
}

 

排序算法

标签:

原文地址:http://www.cnblogs.com/hzxscyq/p/5574511.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!