数据结构与算法八: 3)排序算法--冒泡排序

590 阅读3分钟

这是我参与8月更文挑战的第8天

关注我,以下内容持续更新

数据结构与算法(一):时间复杂度和空间复杂度

数据结构与算法(二):桟

数据结构与算法(三):队列

数据结构与算法(四):单链表

数据结构与算法(五):双向链表

数据结构与算法(六):哈希表

数据结构与算法(七):树

数据结构与算法(八):排序算法

数据结构与算法(九):经典算法面试题

冒泡排序

冒泡排序的简单实现

冒泡排序是简单的交换排序. 交换排序的核心是交换,其主要思想是在待排序序列中选两个记录,将它们的关键码比较,如果反序则交换他们的位置.

冒泡排序的基本思想

  1. 将整个待排序的记录序列划分成有序区和无序区,初始状态有序区为空,无序区包括所有待排序的元素;

  2. 对无序区从前向后依次两两比较相邻记录的关键码,如果反序则交换。每一轮循环后,都使无序区中关键字值最大的记录进入有序区:第一轮循环后最大值已冒泡到最右边,第二轮排序后第二大的值已冒泡到右边第二个位置;

  3. 对于n个元素的序列,最多经过n-1轮冒泡排序,就可以将所有元素排好序

冒泡排序.png

代码实现

//1.冒泡排序
-(void)buddleSort:(NSMutableArray*)arr{
    for (int i = 0; i<arr.count; i++) {
        for (int j = 0; j<arr.count-1-i; j++) {
            if ([arr[j] intValue] > [arr[j+1] intValue]) {
                NSNumber*tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;
            }
        }
    }
}

冒泡排序的优化

优化一

假设我们把排序arr[]={1,2,3,4,5,6,7,8,10,9}进行冒泡排序,第一趟排序后将10和9交换后,所有元素已经有序,接下来的8趟排序就是多余的,什么也没做。所以我们可以在交换的地方加一个标记,如果那一趟排序没有交换元素,说明这组数据已经有序,不用再继续下去。

适用于连片有序而整体无序的数据(例如:1, 2,3 ,4 ,7,6,5)。

-(void)buddleSortOptimize1:(NSMutableArray*)arr{
    for (int i = 0; i<arr.count; i++) {
        int flag = 0;
        for (int j = 0; j<arr.count-1-i; j++) {
            if ([arr[j] intValue] > [arr[j+1] intValue]) {
                NSNumber*tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp
                flag = 1;//标记交换过元素
            }
        }
        if (flag == 0) {//如果没有交换过元素,则已经有序
            return;
        }
    }
}

优化二

假如上轮循环中pos位置后边没有进行交换,说明pos后边是有序的,下一轮就比较pos前边的元素就可以了

优化思路:记录每轮循环最后一次交换的位置,下一次排序从第一个比较到上次记录的位置结束即可。

适用于前面大部分是无序而后边小半部分有序的序列(1,2,5,7,4,3,6,8,9,10)

-(void)buddleSortOptimize2:(NSMutableArray*)arr{

    int pos = 0;//标记每轮循环最后一次交换的位置
    int k = (int)arr.count-1;//内层循环比较到的位置

    for (int i = 0; i<arr.count; i++) {

        int flag = 0;

        for (int j = 0; j<k; j++) {
            if ([arr[j] intValue] > [arr[j+1] intValue]) {
                NSNumber*tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;
                flag = 1;//标记交换过元素
                pos = j;//标记每轮循环最后一次交换的位置
            }
        }
        
        if (flag == 0) {//如果没有交换过元素,则已经有序
            return;
        }
        
        k = pos;//更新k
    }
}