每天学习算法系列—内部排序之归并排序和快速排序

每天学习算法系列—内部排序之归并排序和快速排序

最近经常在CSDN逛,看了不少博客,写的非常好,一直想写博客,却总是找各种借口推掉,无论写的好与坏都要坚持写下去,每天写一点点。

也在学习算法,想动手写一下,也参考了很多网友写的博客。

算法介绍:

排序算法分为内部排序算法和外部排序算法,内部排序算法:如果整个排序过程不需要访问外存就能完成,即可以称为内部排序算法。外部排序:由于计算机内存容量有限,当大批量的数据进行排序时,不可能全部装入内存,即待排序的元素都存储在外存中。

将归并排序和快速排序放在一起比较,他们都是采用分治的方法进行的排序。


1、归并排序:将含有n个元素的待排序序列看成n个长度为1的有序子序列,将他们两两合并,得到长度为2的若干个子序列,再对这些子序列两两合并.......一直重复到长度为n,这时排序就完成了。


2、算法示意图如下:


3、程序代码如下:

/*************************************************************************
    > File Name: mergesort.cpp
    > Author: kanty
    > Mail: jiakang906@126.com 
    > Created Time: 2014年03月12日 星期三 22时56分43秒
 ************************************************************************/
#include<iostream>
using namespace std;

void Merge_Step(int *a,int *b,int start,int mid,int end)
{
    int i,j,k;
    i=start;
    j=mid+1;
    k=0;
    //比较a中前后两个子序列中的元素大小,小的存到b中
    while(i<=mid&&j<=end)
    {
        if(a[i]<=a[j])
        b[k++]=a[i++];
        else
        b[k++]=a[j++];
    }
    //将剩余没有比较的元素直接复制到b中
    while(i<=mid)
    b[k++]=a[i++];
    while(j<=end)
    b[k++]=a[j++];
    //将数组b中元素复制给a,注意start别忘了,从start开始的
    for(i=0;i<k;i++)
    a[start+i]=b[i];
}
void Merge(int *a,int *b,int start,int end)
{
    if(start<end)
    {
        int mid=(start+end)/2;
        Merge(a,b,start,mid);//左递归
        Merge(a,b,mid+1,end);//右递归
        Merge_Step(a,b,start,mid,end);//每个子序列都排序
    }
}
void Merge_Sort(int *array,int len)
{
    int *brray=new int[len*sizeof(int)];
    Merge(array,brray,0,len-1);
    delete [] brray;
    brray=0;
}
int main()
{
    int i,len;
    cout<<"please input a number of array: ";
        while(left<right && array[right]>base)
        //首先最后一个数与基准比较,若大于基准,下标左移
        --right;
        array[left]=array[right];//否则右边数复制到左边
        while(left<right && array[left]<base)
        ++left;
        array[right]=array[left];
    }

    array[left]=base;
    return left;
}
void Quick_sort(int *array,int left,int right)
{
    int mid;
    if(left<right)
    {
        mid=Division(array,left,right);
        Quick_sort(array,left,mid-1);//左序列递归,对左序列进行排序
        Quick_sort(array,mid+1,right);//右序列递归,对右序列进行排序
    }
}
int main()
{
    int num;
    cout<<"请输入要排序的数组个数: ";
    cin>>num;
    int *array=new int[num*sizeof(int)];//开辟一个空间
    cout<<endl<<"请输入 "<<num<<" 个数: ";
    for(int i=0;i<num;i++)
    cin>>array[i];

    Quick_sort(array,0,num-1);//调用快速排序算法

    cout<<endl<<"排序后:"<<endl;
    for(int i=0;i<num;i++)
    cout<<array[i]<<"  ";
    delete [] array;//释放数组
    array=0;//清空指针
    return 0;
}

4、 快速排序:通过一遍排序将需要排序的数据划分为两部分,使其中一部分数据比另一部分数据小,然后再分别对这两部分数据继续进行这种排序,按此规则继续,直到每一部分为空,或者只含有一个数时,整个排序就结束,这是一种分治策略,将大批的数据逐步分解。


5 算法示意图如下:

File:Partition example.svg


6、快速排序的程序代码如下:

/*************************************************************************
    > File Name: quicksort1.cpp
    > Author: kanty
    > Mail: jiakang906@126.com 
    > Created Time: 2014年03月14日 星期五 13时22分54秒
 ************************************************************************/

#include<iostream>
using namespace std;


int Division(int *array,int left,int right)
{
    int base=array[left];//设定基准
    while(left<right)
    {
        while(left<right && array[right]>base)
        //首先最后一个数与基准比较,若大于基准,下标左移
        --right;
        array[left]=array[right];//否则右边数复制到左边
        while(left<right && array[left]<base)
        ++left;
        array[right]=array[left];
    }

    array[left]=base;
    return left;
}

void Quick_sort(int *array,int left,int right)
{
    int mid;
    if(left<right)
    {
        mid=Division(array,left,right);
        Quick_sort(array,left,mid-1);//左序列递归,对左序列进行排序
        Quick_sort(array,mid+1,right);//右序列递归,对右序列进行排序
    }
}

int main()
{
    int num;
    cout<<"请输入要排序的数组个数: ";
    cin>>num;
    int *array=new int[num*sizeof(int)];//开辟一个空间
    cout<<endl<<"请输入 "<<num<<" 个数: ";
    for(int i=0;i<num;i++)
    cin>>array[i];

    Quick_sort(array,0,num-1);//调用快速排序算法

    cout<<endl<<"排序后:"<<endl;
    for(int i=0;i<num;i++)
    cout<<array[i]<<"  ";
    delete [] array;//释放数组
    array=0;//清空指针
    return 0;
}







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值