冒泡排序(双向)

基本算法思想:
(1)双向冒泡排序是冒泡排序的一种优化,它的基本思想是首先将第一个记录的关键字和第二个记录的关键字进行比较,若为“逆序”,则将两个记录交换,然后比较第二个记录和第三个记录的关键字。依次类推,直至第n-1个记录的关键字和第n个记录的关键字比较过为止。这是第一趟冒泡排序,其结果是使得关键字最大的记录被安置到最后一个记录的位置上。
(2)第一趟排序之后进行第二趟冒泡排序,将第n-2个记录的关键字和第n-1个记录的关键字进行比较,若为“逆序”,则将两个记录交换,然后比较第n-3个记录和第n-2个记录的关键字。依次类推,直至第1个记录的关键字和第2个记录的关键字比较过为止。其结果是使得关键字最小的记录被安置到第一个位置上。
(3)再对其余的n-2个记录进行上述同样的操作,其结果是使关键字次大的记录被安置到第n-1个记录的位置,使关键字次小的记录被安置到第2个记录的位置。

双向冒泡排序的优化:
(1)如果发现一次内层循环没有经过任何交换,则说明array已经排序完毕,所以加入标识项,以便跳出循环。
(2)在冒泡排序(单向)这片文章中,我们探讨过一种极端情况:array长度为n,但是只有0,1元素未排序时,由于我们内层循环长度的设定依据是,i次排序array的后i-1个元素是排序好的,但实际上i次排序的循环长度取决于i-1次排序时最后的交换位置,例如i-1次排序的最后交换位置是index,则表明index之后的元素都已经排序完毕,我们只需要记录这个Index就得到了下次(i次)的循环长度。

具体实现见代码:

#include <iostream>

void swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 冒泡排序(双向)
void BidBubbleSort(int arr[], int len)
{
    int left, right, flag, i;
    int lastSwapPosTemp = 0;
    left = 0;
    right = len - 1; // 注意,left和right的初始值,决定了下面for循环中应使用“<”或“<=”,“>”或">="。
    while(left < right)
    {
        flag=0;

        for(i=left; i<right; i++) // 正向冒泡
        {
            if(arr[i] > arr[i+1]) // 找到剩下中最大的
            {
                swap(&arr[i], &arr[i+1]);
                flag = 1;    // 标志, 有数据交换
                lastSwapPosTemp = i; // 此处lastSwapPosTemp的最终值,就是本轮正向冒泡中,最后一次交换数据的位置。该位置之后的数据都已经排序好了。
            }
        }
        right = lastSwapPosTemp;


        for( i=right; i>left; i--) // 反向冒泡
        {
            if(arr[i] < arr[i-1])   // 找到剩下中最小的
            {
                swap(&arr[i], &arr[i-1]);
                flag = 1;
                lastSwapPosTemp = i; // 此处lastSwapPosTemp的最终值,就是本轮反向冒泡中,最后一次交换数据的位置。该位置之前的数据都已经排序好了。
            }
        }
        left = lastSwapPosTemp;

        if( !flag )
            break;

    }
}


// 打印
void print(int arr[], int n)
{
    for (int i=0; i<n; i++)
        printf("%d  ", arr[i]);

    printf("\n");
}



int main(int argc, const char * argv[]) {

    int arr[] = { 8, 4, 2, 3, 5, 1, 6, 9, 0, 7 };
    int len = sizeof(arr)/sizeof(int);

    // 排序前数组序列
    print(arr, len);

    BidBubbleSort(arr, len);

    // 排序后数组序列
    print(arr, len);

    return 0;
}
  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值