部分排序算法的实现

前言

讲述部分排序算法的实现与利弊
我认为你们掌握冒泡排序,归并排序,快速排序这三种足以

冒泡排序

概念:

在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现他们的排序与排序要求相反时,就将他们互换。

代码实现

#include <cstdio>
int a[11] = {0,7,8,7,9,3,8,1,3,5,2};
/*     冒泡排序     */
int main()
{
    int i,j;
    int n = 10;
    int tmp;
    for(i=1;i<n;i++)
    {
        for(j=1;j<n;j++)
        {
            if(a[j] > a[j+1])//升序排序,即从小到大排序
            {
                tmp = a[j+1];
                a[j+1] = a[j];
                a[j] = tmp;
            }
        }
    }
    for(i=1;i<=10;i++)printf("%d ",a[i]);
    return 0;
}

冒泡排序优缺点

优点:稳定

缺点:时间复杂度为O(n^2)

因为有两层循环,n*n

归并排序

概念:

先将整个待排序元素序列分割成若干子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序(因为直接插入排序在元素基本有序的情况下,效率很高)

这个排序算法还有一个特殊用处:求逆序对(以后再讲)

代码实现:


#include <cstdio>
#include <cstring>
int a[9] = {0,7,8,9,3,1,3,5,2};
int b[9];//用来存放某个阶段的局部的排序,然后再覆盖到a数组上
/*     归并排序     */
/*
	我用|将其隔开
    递归
    7 8 9 3|1 3 5 2
    7 8|8 3|1 3|5 2
    7|8|8|3|1|3|5|2 ---->分割到最小
    回溯
    7 8|3 8|1 3|2 5
    3 7 8 8|1 2 3 5
    1 2 3 3 5 7 8 8
*/
void merge(int l,int mid,int r)
{
    int ll = l;
    int rr = mid+1;
    int sit = l-1;
    while(1)
    {
        if(ll > mid && rr > r)break;//要排序的数全都搞好了,退出。
        if(a[ll]<a[rr])
        {
            if(ll <= mid)
            {
                b[++sit] = a[ll];
                ll++;
            }
            else {b[++sit] = a[rr];rr++;}
        }
        else 
        {
            if(rr <= r)
            {
                b[++sit] = a[rr];
                rr++;
            }
            else {b[++sit] = a[ll];ll++;}
        }
    }
    int i;
    for(i=l;i<=r;i++)a[i] = b[i];//覆盖
}
void mergesort(int l,int r)
{
    int mid;
    if(l<r)
    {
        mid = (l + r) / 2; 
        mergesort(l,mid);//涉及递归知识
        mergesort(mid+1,r);
        merge(l,mid,r);//当这两边都排序完毕的时候再将这两个进行排序
    }
}
int main()
{
    int i,j;
    int n = 10;
    int tmp;
    mergesort(1,8);//左端点和右端点
    for(i=1;i<=8;i++)printf("%d ",a[i]);
    return 0;
}

实不相瞒,这个我以前也不是很懂,就刚才写这个地方的时候查查资料自己想了想就写出来了。很简单的。
归并排序还涉及到了分治思想,能思考出来时怎么一回事吗?
对于原理不是很懂的,可以在网上找一找归并排序过程的图,再想一想。我的代码就代表了过程。
时间复杂度(nlog2n) 稳定且比冒泡快

快速排序

这是这三个之中最难理解的一个算法(个人认为)
其基本思想是:

扫描二维码关注公众号,回复: 8871218 查看本文章
1、先从数列中取出一个数作为基准数

2、分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边

3、再对左右区间重复第二步,直到各区间只有一个数

代码实现

#include <cstdio>
#include <cstring>
int a[9] = {0,7,8,9,3,1,3,5,2};
/*     快速排序     */
void qsort(int l,int r)
{
    int i,j;
    int tmp;
    if(l < r)
    {
        i = l;
        j = r;
        tmp = a[l];/*
        			我们取第L个数为基
        			准值,即这一个区间的
        			第一个值。可换成别的
        			*/
        while(i < j)
        {
       		//从右向左找第一个小于tmp的数
            while(i < j && a[j] >= tmp)j--;
            if(i < j)a[i++] = a[j];
            //从左向右找第一个大于等于tmp的数
            while(i < j && a[i] <  tmp)i++;
            if(i < j)a[j--] = a[i];
        }
        a[i] = tmp;
        qsort(l,i-1);
        qsort(i+1,r);
    }
}
int main()
{
    int i,j;
    qsort(1,8);
    for(i=1;i<=8;i++)printf("%d ",a[i]);
    return 0;
}

总结

加强版冒泡,不稳定,极端情况下会退化成冒泡排序

说明

关于排序过程的图,网上都有,可以自己找找看看。这里不再过多叙述。

发布了36 篇原创文章 · 获赞 29 · 访问量 3936

猜你喜欢

转载自blog.csdn.net/YUK_103/article/details/103910777