交换排序之冒泡排序

               交换排序是通过交换记录在表中的位置来实现排序的。交换排序的思想是:两两比较带排记录的关键字,一旦发现两个记录的次序与排序要求相逆,则交换这两个记录的位置,直到表中没有逆序为止。


         冒泡排序:对R[0]~R[n-1]这n个记录的冒泡排序过程是:第一趟从第0个记录R[0]开始到第n个记录R[n-1]为止,对n-1对相邻的两个记录进行两两比较,若与排序要求相逆,则交换两者位置,这样经过一趟的比较、交换之后,具有最大关键值的记录就被交换到末尾R[n-1]位置上。第二趟从第0个记录R[0]开始到第n-2个记录R[n-2]为止继续重复上述的比较与交换,这样具有次大关键字的记录就被交换到R[n-2]的位置上。如此重复,经过n-1趟这样的比较和交换之后,R[0]~R[n-1]这n个记录议案关键字有序。这个排序过程就像一个个往上(往右)冒泡的气泡,最轻的气泡先冒上来(到达R[n]位置),较重的气泡后冒上来,因此形象的称之为冒泡排序。

      冒泡排序最多进行n-1趟,在某趟的两两记录关键字的比较中,如果一次交换都未发生,则表明R[0]~R[n-1]中的记录已经有序,这时可结束排序过程。

    冒泡排序算法如下:

#include <stdio.h>

void BubbleSort ( int array[] ,int n);

int main()
{
    int array[10] = {35,12,89,0,87,89,63,654,32,2}, i;
    BubbleSort(array,10);
    for (i = 0; i < 10; i++)
    {
        printf("%d  ", array[i]);
    }
    return    0;
}
void BubbleSort (int array[] ,int n)
{
    int i,j,swap;
    for (i = 0; i < n-1; i++)                            //进行n-1趟排序
    {
        swap = 0;                                        //设置交换变量
        for(j = 0; j < (n-1)-i; j++)                     //对R[0]~R[n-i]记录进行两两排序
        {
            if(array[j] > array[j+1])                    //如果左边数大于右边数则交换位置
            {
                swap = array[j];
                array[j] = array[j+1];
                array[j+1] = swap;
            }
        }
        if (swap == 0)                                  //swap==0说明本趟没有交换发生则结束排序(已经排好)
            break;
        printf("\n");
    }
}

排序过程示意图:

            

我们加上相应的printf语句看结果与我们预期是否一致:

 上述冒泡排序算法是从左向右进行冒泡排序的,假定关键字越大,气泡越轻。当然我们也可以参考此算法设计出从右往左的排序算法。

从空间效率上看,冒泡只用了一个辅助单元;从时间效率上看,最好的情况是待排序列已经全部有序。这样冒泡排序在第一趟中排序过程中就没有发生交换,所以一趟结束之后即排序结束。也即,只在第一趟中进行了n-1次比较。最坏的情况是待排序记录按逆序排序,所以共需进行n-1趟排序,且第i趟需要进行n-1次比较。所以:

总比较次数 = ∑(n - i)=1/2n(n-1)

时间复杂度为O(n²),交换记录的次数与比较记录的次数相同,最坏的情况也是发生在待排序记录按逆序排列时。

      但是,当具有n个记录的待排序列已经基本有序,但是最小关键字记录位于序列最后,这时仍需要n-1次排序,这样不免降低了排序的效率。因此我们可以考虑双向冒泡排序方法来解决这一问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值