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

交换排序

时间:2016-05-04 10:10:35      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:

  交换排序是指在排序过程中,通过比较待排序记录序列中元素间关键字的比较,将存储位置进行交换来达到排序目的的方法。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

//冒泡排序,一次排序将无序区里面最大的移到最右边
void BubbleSort(int* a,int length)
{
    int i=0,j=0;
    int temp;
    for(i=length-1;i>0;i--)
    {
        for(j=0;j<i;j++)
        {
            if(a[j+1]<a[j])
            {
                temp=a[j+1];
                a[j+1]=a[j];
                a[j]=temp;
            }
        }
    }
}
//优化后的冒泡排序:一点是如果一趟排序没有进行任何交换,那么说明已经有序,这样程序应该退出;
//                 一点是一趟排序中,最后一次交换的地方,此时的j以后的全部有序了,因此下次可从此时的j开始;
void BetterBubbleSort(int* a,int length)
{
    int i=0,j=0;
    int temp,m=0,n=length-1,last;
    for(i=length-1;i>0;i=n)
    {
        m=0;
        last=n;
        for(j=0;j<=last;j++)
        {
            if(a[j+1]<a[j])
            {
                temp=a[j+1];
                a[j+1]=a[j];
                a[j]=temp;
                m=1;
                n=j;
            }
        }        
        if(m==0)//说明此时无序区里的所有数据已经有序,可以退出
            break;
    }
}
//我自己写的快排,可以清晰的看出它的原理
void QuickSort(int* a,int start,int end)
{
    int s=start;
    int e=end-1;
    int m=s;
    int temp;
    while(s<e)
    {
        while(a[e]>=a[m]&&s<e)
            e--;
        if(a[e]<a[m])
        {
            temp=a[e];
            a[e]=a[m];
            a[m]=temp;
            m=e;
        }
        while(a[s]<=a[m]&&s<e)
            s++;
        if(a[s]>a[m])
        {
            temp=a[s];
            a[s]=a[m];
            a[m]=temp;
            m=s;
        }
    }
    if(m>start+1)
        QuickSort(a,start,m);
    if(m<end-1)
        QuickSort(a,m+1,end);
}
//更好的快速排序
void BetterQuickSort(int* a,int start,int end)
{
    int s=start;
    int e=end;
    int m=a[s];
    while(s<e)
    {
        //还有一点要格外注意当有重复数据时,比如这里2个5,程序会进入到死循环,调试发现此时a[e]=a[s],但是e与s不相等,所以要在while循环条件里加上>=或<=。
        while(s<e&&a[e]>=m)
            e--;
        a[s]=a[e];
        while(s<e&&a[s]<=m)
            s++;
        a[e]=a[s];
        //我自己设的数组太长了,所以换了一个小的,假设数组a是3,2,5,8,1,9。经过一次while后为1 2 5 8 5 9,现在e=4,s=2
        //这个地方我刚开始一直觉得还需要加上一个a[s]=m;,想清楚后才发现并不需要加,原因可分为2种情况,
        //首先下一次执行while循环时是从后往前进行比较的,正好上一次a[e]=a[s]导致a[e]是大于m的,所以e一直减减直到条件不满足退出,然后再在while循环后执行a[s]=m;
        //第二种情况是假设把8替换为0,这样的话e将变为3,此时s=2数组为1 2 0 0 5 9,注意接下来是s开始向前增加了,正是由于将较小值放在前面,所以s一直加加直到条件不满足退出
        //当需要多次while循环时将会完成多次上述2种情况,总之就是可以保证s与e一直在增加与减少。
    }
    a[s]=m;
    if(s>start+1)
        BetterQuickSort(a,start,s-1);
    if(s<end-1)
        BetterQuickSort(a,s+1,end);
}

void main()
{
    //交换排序
    int a[]={5,2,7,23,5,10,12,1,21};
    int length=9;
    int i=0;
    //冒泡排序,序列越有序它的效率越高。它是一种稳定的排序方法,平均时间复杂度为O(n^2)
    //BubbleSort(a,length);
    //BetterBubbleSort(a,length);

    //快速排序,可以看出它适合杂乱无章的数据,如果数据有序的话可能一次只会划分很小的区域。
    //对于时间复杂度,假设一种极端情况,每次选择的都是最小的或最大的,设序列区长度为k,那这样就直接比较了k-1次。整个时间复杂度是(k-1)*(k-2)..,这样就退化为冒泡了,所以时间复杂度是O(n^2);
    //最好情况是每次划分序列后这两个序列长度相等,那一次排序,就算你是划分了几个序列区域去排序。我自己举例子发现第一次比较n-1次,第二次划分一般那就是n/2-1,但是由于有2部分所以要乘以2。
    //也就是说一次排序比较的次数是n阶函数,而划分一半的次数是lbn,故时间复杂度是O(nlbn)
    //QuickSort(a,0,length);
    BetterQuickSort(a,0,length-1);
    for(;i<length;i++)
        printf("%d ",a[i]);
}
 

 

交换排序

标签:

原文地址:http://www.cnblogs.com/fangyz/p/5425751.html

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