冒泡排序基本代码及其优化

冒泡排序是一种交换排序,它的基本思想是:两两比较序列中造句记录的关键字,如果反序则交换,直到没有反序的记录为止。它的运行过程如下(以升序排序为例):

    1.   比较造句的元素。如果第一个比第二个大,就交换他们两个。
    2.   对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
    3.   针对所有的元素重复以上的步骤,除了最后一个。
    4.   持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

  比如待排序序列数组为:9 2 6 8 7 3 1 0 4 5,将其升序排序成序列0 1 2 3 4 5 6 7 8 9,按照上述冒泡法的运行过程有:

  9 2 6 8 7 3 1 0 4 5   相邻记录关键字作比较,9>2交换得到序列:2 9 6 8 7 3 1 0 4 5

  2 9 6 8 7 3 1 0 4 5   同样的,9>6,交换后:2 6 9 8 7 3 1 0 4 5

  2 6 9 8 7 3 1 0 4 5   9>8 交换得到:2 6 8 9 7 3 1 0 4 5

  …..

  2 6 8 7 3 1 0 4 9 5  9>5 交换 得到:2 6 8 7 3 1 0 4 5 9

  在经过N-1次比较后可以看到关键字最大的元素9经过升序冒泡后已经到了序列的最尾端,这个过程称为第一趟冒泡排序。接着再从序列的第一对相邻元素开始进行第二趟排序:

  2 6 8 7 3 1 0 4 5 9 ——>2 6 8 7 3 1 0 4 5 9

  2 6 8 7 3 1 0 4 5 9——>2 6 8 7 3 1 0 4 5 9

  2 6 8 7 3 1 0 4 5 9——>2 6 7 8 3 1 0 4 5 9

  ….

  2 6 7 3 1 0 4 8 5 9 ——>2 6 7 3 1 0 4 5 8 9

  第二趟排序完成,把关键字8升到了序列倒数第二个位置。可以发现,第二趟排序的比较次数比第一趟少了一次,8与最后的9没有进行比较。

  重复这个过程进行N-1趟的比较之后,可完成对整个序列的冒泡排序。

  按照这个思路,相应的代码为:

void BubbleSort1(int array[],int arrayLength)
{
    int i ,j ;
    for(i=0;i<arrayLength-1;++i) //进行N-1趟比较
    {
        for(j= 1;j<arrayLength-i;++j) //每趟比较中的内循环
            if(array[j]<array[j-1])  //即相邻元素之间的比较
                Swap(array[j],array[i]);  //反序,进行交换
    }
}

  注意到我在写冒泡排序定义的时候,用红色字体强调了冒泡排序进行比较的是相邻的元素,如下面这段代码,在结构上虽然很像冒泡,实际上只是简单的交换排序:

void Sort(int array[],int arrayLength)
{
    int i ,j ;
    for(i=0;i<arrayLength-1;++i)
    {
        for(j=i+1;j<arrayLength;++j)
            if(array[j]<array[i])  //这里比较的非相邻的元素。该算法不是冒泡
                Swap(array[j],array[i]);
    }
}

  这种算法做了大量的无用的交换操作,效率是非常低下的。

  排序算法还可以进行优化,设置一个标志域flag,如果某一趟排序发生了变换,那么flag为true。如果某一趟排序没有发生交换,则说明序列已经有序了,不必再进行继续的比较操作,此时flag为false。

{
    int i ,j ;
    bool flag = true;
    for(i=0;i<arrayLength-1&&flag;++i)
    {
        flag = false;
        for(j= 1;j<arrayLength-i;++j)
            if(array[j]<array[j-1])
            {
                Swap(array[j],array[j-1]);
                flag = true;  //有交换,表明当前序列尚未有序,标志为ture
            }
    }
}

  冒泡法还有另外一种优化,即只对无序的关键字进行排序。假设有序列array={2,1,5,4,0,6,7,8,9}按升序排序,则只需对无序区{2,1,5,4,0}进行排序即可。使用一个标志来记录无序区的范围:

void BubbleSort3(int array[],int arrayLength)
{
    int flag = arrayLength-1;
    while(flag>0)
    {
        for(int i = 0;i<arrayLength-1;i++)
        {
            int k = flag;
            flag=0;
            for(int j = 0;j<k;++j)
                if(array[j]<array[j+1])
                {
                    Swap(array[j],array[j+1]);
                    flag=j;  //记录无序区的末尾位置
                }
        }
    }
}

  当然,这种优化情况还是有点特殊的,但序列完全反序时起不到优化作用的。

总体来说,冒泡排序的效率是较为低下在,在数据量小的情况下可以使用,否则应该选择其他的排序算法。

本文章由 造句大全 www.zaojuzi.com  整理发布

时间: 2024-08-25 17:57:50

冒泡排序基本代码及其优化的相关文章

C#冒泡排序法及优化

冒泡排序法及优化: static void Main(string[] args) { int[] sums = { 20, 2, 1, 26, 27, 28 }; int compareCount = 0; //冒泡排序法 for (int i = 0; i < sums.Length - 1; i++) //总共要比较的趟数 { for (int j = 0; j < sums.Length - 1 - i; j++) //每趟中要比较的次数 { if (sums[j] > sums

JS 冒泡排序从学到优化

目的:理解算法 深化算法 冒泡排序: 直接上动图好于文字 一个冒泡实例 45,67,23,88,21,6,99// 第一轮 6次// 45 67 23 88 21 6 99// 45 23 67 88 21 6 99// 45 23 67 88 21 6 99// 45 23 67 21 88 6 99// 45 23 67 21 6 88 99// 45 23 67 21 6 88 99 // 第二轮 6次// 23 45 67 21 6 88 99// 23 45 67 21 6 88 99

冒泡排序及其算法优化分析

1.基本冒泡排序 冒泡排序的基本思想:假设被排序的记录数组d[1...N]垂直竖立,将每个记录d[i]看作是一个气泡,那么重的气泡就会向下下沉,轻的气泡就会向上升.每次都是相邻的两个气泡d[i]和d[i+1]进行比较.如果d[i]>d[i+1],那么就交换两个气泡,然后在比较d[i+1]和d[i+2],以此类推,知道所有的气泡都有序排列.假设排序20,37,11,42,29. 第1次冒泡:20.37,11,42,29 d[0]和d[1]比较 第2次冒泡:20,11,37,42,29 d[1]和d

冒泡排序算法及其优化

思想: 同之前介绍的两种排序方式一样,冒泡排序也是最简单最基本的排序方法之一.冒泡排序的思想很简单,就是以此比较相邻的元素大小,将小的前移,大的后移,就像水中的气泡一样,最小的元素经过几次移动,会最终浮到水面上. 举例分析说明一下,如下数据: 2 7 4 6 9 1 首先比较最后两个数字,发现1比9小,于是前移 2 7 4 6 1 9 然后比较6和1 2 7 4 1 6 9 继续前移,然后是4和1 2 7 1 4 6 9 7和1比较 2 1 7 4 6 9 2和1 1 2 7 4 6 9 至此,

冒泡排序--两种优化方式

原始版本 void bubble_sort(int arr[],int n){ int tmp; for (int i = 0; i < n; ++i) { for (int j = 0; i < n; ++j) { if (arr[j] < arr[j+1]) { tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; } } } } 优化版本一 如果内层循环没有进行交换,说明后面的元素已经有序,则不需要继续循环.因此,我们可以设置一个标记来标

冒泡排序和一点优化,直接上代码

function maopao($arr){ $len = count($arr);//获取数组的长度 //有多少个数组元素就最多就要排n-1次 for ($j=0;$j<$len-1;$j++){ $flag = true;//这个flag就是判断有没有进入里面的for,不进去就代表排好了,就直接退出当次循环 //没个元素比较的次数,当前面排过 j次时,就以为着这j次肯定是排好的 for ($i=0;$i<$len-1-$j;$i++){ if($arr[$i]>$arr[$i+1])

冒泡排序优化JAVA

本文对传统的冒泡排序进行了一些优化,减少了循环次数. 时间复杂度 若文件的初始状态是正序的,一趟扫描即可完成排序.所需的关键字比较次数 C 和记录移动次数 M 均达到最小值: C(min)=n-1 , M(min)=0 .所以,冒泡排序最好的时间复杂度为 O(n); 若初始文件是反序的,需要进行  趟排序.每趟排序要进行  次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置.在这种情况下,比较和移动次数均达到最大值: 冒泡排序的最坏时间复杂度为O(n^2) . 综上

冒泡排序-优化后的

时间复杂度 若文件的初始状态是正序的,一趟扫描即可完成排序.所需的关键字比较次数  和记录移动次数  均达到最小值:  ,  .所以,冒泡排序最好的时间复杂度为  . 若初始文件是反序的,需要进行  趟排序.每趟排序要进行  次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置.在这种情况下,比较和移动次数均达到最大值: 冒泡排序的最坏时间复杂度为 . 综上,因此冒泡排序总的平均时间复杂度为 . 算法稳定性 冒泡排序就是把小的元素往前调或者把大的元素往后调.比较是相邻

冒泡排序以及冒牌排序优化算法

冒泡排序是最常用的排序算法,在笔试中也非常常见,能手写出冒泡排序算法可以说是基本的素养. 算法重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,这样越大的元素会经由交换慢慢“浮”到数列的顶端. 时间复杂度 算法稳定性 冒泡排序就是把小的元素往前调或者把大的元素往后调.比较是相邻的两个元素比较,交换也发生在这两个元素之间.所以,如果两个元素相等,是不会再交换的:如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺