冒泡排序与选择排序的不同、快速排序与选择排序的结合
冒泡排序可以说是最简单的排序了。我们学习C语言循环的时候都会提到。
可见这是一种浅而易懂的排序算法!
但不见得这种算法就没用处。首先,他很容易理解,这样在各种教材中比较适合拿来“开门见山”。其次是他很稳定。 若明确知道即将排的数字很混乱,随机性很强,则用冒泡排序也未偿不可。 谁让他始终是O(n^2)呢。
冒泡排序法代码:
从中我们可以看到,每次都会将后面的L-(i+1)个数拿来和a[i]比较,然后将小一点的换到前面。有人就觉得啊,这个每次都交换很费性能,影响效率。所以他们就将a[j]和a[i]比较后的最小值的下标记下来,当比较完之后,最后记下的下标就是最小的值的下标,然后再进行一次交换。于是便有了选择排序法。
选择排序法代码:
虽然,我们并没有根本性地扭转冒泡排序的地位。但效率是有明显提升的,至少减少了L*(L-1)-L = L*(L-2) = L^2 - 2*L次交换!
另外,目前广为使用的快速排序和选择排序联合使用,也会有意想不到的提升!
众所周知,当用快速排序法排序时,划分到很细的时候,明显很亏。 比如:两三个数排序却要划分成两堆,这样很划不来。所以,我们可以设定一个阀值,当快速排序划分到一定粒度的时候,便采用选择排序。 至于这个阀值,可以通过performace来测试,以得到一个“最优值”
可见这是一种浅而易懂的排序算法!
但不见得这种算法就没用处。首先,他很容易理解,这样在各种教材中比较适合拿来“开门见山”。其次是他很稳定。 若明确知道即将排的数字很混乱,随机性很强,则用冒泡排序也未偿不可。 谁让他始终是O(n^2)呢。
冒泡排序法代码:
 1 void BubbleSort(int a[],int l)
void BubbleSort(int a[],int l)
2 {
{
3 for(int i = 0; i< l;++i)
    for(int i = 0; i< l;++i)
4 {
    {
5 for(int j = i+1; j< l; ++j)
        for(int j = i+1; j< l; ++j)
6 {
        {
7 if(a[j]<a[i])
            if(a[j]<a[i])
8 {
            {
9 int t = a[i];
                int t = a[i];
10 a[i] = a[j];
                a[i] = a[j];
11 a[j] = t;
                a[j] = t;
12 }
            }
13 }
        }
14 }
    }
15 }
}
 void BubbleSort(int a[],int l)
void BubbleSort(int a[],int l)2
 {
{3
 for(int i = 0; i< l;++i)
    for(int i = 0; i< l;++i)4
 {
    {5
 for(int j = i+1; j< l; ++j)
        for(int j = i+1; j< l; ++j)6
 {
        {7
 if(a[j]<a[i])
            if(a[j]<a[i])8
 {
            {9
 int t = a[i];
                int t = a[i];10
 a[i] = a[j];
                a[i] = a[j];11
 a[j] = t;
                a[j] = t;12
 }
            }13
 }
        }14
 }
    }15
 }
}从中我们可以看到,每次都会将后面的L-(i+1)个数拿来和a[i]比较,然后将小一点的换到前面。有人就觉得啊,这个每次都交换很费性能,影响效率。所以他们就将a[j]和a[i]比较后的最小值的下标记下来,当比较完之后,最后记下的下标就是最小的值的下标,然后再进行一次交换。于是便有了选择排序法。
选择排序法代码:
 1 void SelectSort(int a[],int l)
void SelectSort(int a[],int l)
2 {
{
3 for(int i = 0; i< l; ++i)
    for(int i = 0; i< l; ++i)
4 {
    {
5 int k=i;
        int k=i;
6 for(int j = i+1; j<l;++j)
        for(int j = i+1; j<l;++j)
7 {
        {
8 
            
9 if(a[j]<a[k])
            if(a[j]<a[k])
10 {
            {
11 k=j;
                k=j;
12 }
            }
13 }
        }
14 int t = a[i];
        int t = a[i];
15 a[i]=a[k];
        a[i]=a[k];
16 a[k]= t;
        a[k]= t;
17 }
    }
18 }
}
 void SelectSort(int a[],int l)
void SelectSort(int a[],int l)2
 {
{3
 for(int i = 0; i< l; ++i)
    for(int i = 0; i< l; ++i)4
 {
    {5
 int k=i;
        int k=i;6
 for(int j = i+1; j<l;++j)
        for(int j = i+1; j<l;++j)7
 {
        {8
 
            9
 if(a[j]<a[k])
            if(a[j]<a[k])10
 {
            {11
 k=j;
                k=j;12
 }
            }13
 }
        }14
 int t = a[i];
        int t = a[i];15
 a[i]=a[k];
        a[i]=a[k];16
 a[k]= t;
        a[k]= t;17
 }
    }18
 }
}虽然,我们并没有根本性地扭转冒泡排序的地位。但效率是有明显提升的,至少减少了L*(L-1)-L = L*(L-2) = L^2 - 2*L次交换!
另外,目前广为使用的快速排序和选择排序联合使用,也会有意想不到的提升!
众所周知,当用快速排序法排序时,划分到很细的时候,明显很亏。 比如:两三个数排序却要划分成两堆,这样很划不来。所以,我们可以设定一个阀值,当快速排序划分到一定粒度的时候,便采用选择排序。 至于这个阀值,可以通过performace来测试,以得到一个“最优值”
 1 void QSort(int a[],int l,int r)
void QSort(int a[],int l,int r)
2 {
{
3 int p;
    int p;
4 if(l<r)
    if(l<r)
5 {
    {
6 if(l-r<= DEFINE_NUMBER)
        if(l-r<= DEFINE_NUMBER)
7 SelectSort(a,l,r);
            SelectSort(a,l,r);
8 else
        else
9 {
        {
10 p = Partition(a,l,r);
            p = Partition(a,l,r);
11 QSort(a,l,p-1);
            QSort(a,l,p-1);
12 QSort(a,p+1,r);
            QSort(a,p+1,r);
13 }
        }
14 }
    }
15 }
}
 void QSort(int a[],int l,int r)
void QSort(int a[],int l,int r)2
 {
{3
 int p;
    int p;4
 if(l<r)
    if(l<r)5
 {
    {6
 if(l-r<= DEFINE_NUMBER)
        if(l-r<= DEFINE_NUMBER)7
 SelectSort(a,l,r);
            SelectSort(a,l,r);8
 else
        else9
 {
        {10
 p = Partition(a,l,r);
            p = Partition(a,l,r);11
 QSort(a,l,p-1);
            QSort(a,l,p-1);12
 QSort(a,p+1,r);
            QSort(a,p+1,r);13
 }
        }14
 }
    }15
 }
}
作者:麒麟子 
出处:http://www.cnblogs.com/qilinzi/
蛮牛专栏:麒麟子 
简介:麒麟子,编程15年,科技创始人,技术作家。
09年进入游戏行业,16年创立成都幼麟科技有限公司。十年从业经验练就了游戏全栈技能,目前专注于手机游戏领域。
版权声明:本文版权归作者和博客园共有,欢迎转载。转载必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 
                    
                


 
     
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号