Vickate_冒泡排序

冒泡排序

冒泡排序是最简单最容易理解的排序算法之一,其思想是通过无序区中相邻记录关键字间的比较和位置的交换,使关键字最小的记录如气泡一般逐渐往上“漂浮”直至“水面”。 冒泡排序的复杂度,在最好情况下,即正序有序,则只需要比较n次。故,为O(n) ,最坏情况下,即逆序有序,则需要比较(n-1)+(n-2)+……+1,故,为O(n²)。


普通冒泡

// 冒泡排序(i控制趟树,j控制每趟的次数)
    NSMutableArray *array = [NSMutableArray arrayWithArray:@[@1, @3, @2, @9, @6, @19, @7]];
    for (int i = 0; i < array.count - 1; i++) {
        for (int j = 0; j < array.count - 1 - i; j++) {
            if (array[j] > array[j+1]) {
                int temp = [array[j] intValue];
                array[j] = array[j + 1];
                array[j+1] = [NSNumber numberWithInteger:temp];
            }
        }
    }
    NSLog(@"%@", array);

看打印的日志

2018-05-18 11:58:20.440305+0800 OCProjectKit[53094:7146542] k = 6
2018-05-18 11:58:20.440474+0800 OCProjectKit[53094:7146542] (
    1,
    2,
    3,
    6,
    7,
    9,
    19
)

k = 6,i 的趟数为6趟


代码优化

添加控制,如果已经排好序,就不再继续排序

NSMutableArray *array = [NSMutableArray arrayWithArray:@[@1, @3, @2, @9, @6, @19, @7]];
    int k = 0;
    BOOL isSort = YES;
    for (int i = 0; i < array.count - 1 && isSort; i++) {
        k++;
        isSort = NO;
        for (int j = 0; j < array.count - i - 1; j++) {
            if (array[j] > array[j+1]) {
                
                int temp = [array[j] intValue];
                array[j] = array[j + 1];
                array[j+1] = [NSNumber numberWithInteger:temp];
                isSort = YES;
            }
        }
        NSLog(@"k = %d", k);
        NSLog(@"%@\n", array);
    }

看打印的日志

2018-05-18 12:02:34.209727+0800 OCProjectKit[53230:7154275] k = 3
2018-05-18 12:02:34.209879+0800 OCProjectKit[53230:7154275] (
    1,
    2,
    3,
    6,
    7,
    9,
    19
)

k = 3,i 的趟数为3趟


鸡尾酒排序

如果到这里,你觉得已经做得很完美了,那么就不用再继续往下看了,如果觉得这个还能再继续优化,那么,双向循环排序了解一下,简称鸡尾酒排序。

要是文艺点的话,可以说是搅拌排序,通俗易懂点的话,就叫“双向冒泡排序”,我想作为码农的话,不可能不知道冒泡排序,冒泡是一个单向的从小到大或者从大到小的交换排序,而鸡尾酒排序是双向的,从一端进行从小到大排序,从另一端进行从大到小排序。

NSMutableArray *array = [NSMutableArray arrayWithArray:@[@1, @3, @2, @9, @6, @19, @7]];
    int k = 0;
    BOOL isSort = YES;
    // 因为是双向比较,所以比较次数为原来数组的1/2次即可。
    for (int i = 0; i < array.count - 1 && isSort; i++) {
        k++;
        isSort = NO;
        // 从前到后的排序 (升序)
        for (int j = 0; j < array.count - i - 1; j++) {
            // 如果前面大于后面,则进行交换
            if (array[j] > array[j+1]) {
                int temp = [array[j] intValue];
                array[j] = array[j + 1];
                array[j+1] = [NSNumber numberWithInteger:temp];
                isSort = YES;
            }
        }
        
        // 从后到前的排序(降序)
        for (int k = (int)array.count - i - 1; k > i; k--) {
            // 如果前面大于后面,则进行交换
            if (array[k - 1] > array[k]) {
                int temp = [array[k] intValue];
                array[k] = array[k - 1];
                array[k - 1] = [NSNumber numberWithInteger:temp];
                isSort = YES;
            }
        }
        NSLog(@"k = %d", k);
        NSLog(@"%@\n", array);
    }

看打印的日志

2018-05-18 13:30:42.665453+0800 OCProjectKit[54426:7224455] k = 2
2018-05-18 13:30:42.665606+0800 OCProjectKit[54426:7224455] (
    1,
    2,
    3,
    6,
    7,
    9,
    19
)

k = 2,i 的趟数为2趟

END

你可能感兴趣的:(Vickate_冒泡排序)