美文网首页iOS
选择、插入、冒泡排序算法解法及实现

选择、插入、冒泡排序算法解法及实现

作者: weiweilong | 来源:发表于2018-03-20 11:20 被阅读5次

冒泡排序:

首先是最熟悉常见的冒泡排序。顾名思义,就像气泡一样,依次将最大(小)值往上浮,直到适当的位置为止。下面看一组无序的数据,使用冒泡排序将其变为有序的。
现有一组无序的数字组成的数组,使用冒泡排序进行排序:

  • 37, 33, 24, 4, 58, 35, 40, 98, 76, 82
排序前 37, 33, 24, 4, 58, 35, 40, 98, 76, 82
第 1 次排序 33, 24, 4, 37, 35, 40, 58, 76, 82, 【98】
第 2 次排序 24, 4, 33, 35, 37, 40, 58, 76, 【82, 98】
第 3 次排序 4, 24, 33, 35, 37, 40, 58, 【76, 82, 98】
第 4 次排序 4, 24, 33, 35, 37, 40, 【58, 76, 82, 98】
第 5 次排序 4, 24, 33, 35, 37, 【40, 58, 76, 82, 98】
第 6 次排序 4, 24, 33, 35, 【37, 40, 58, 76, 82, 98】
第 7 次排序 4, 24, 33, 【35, 37, 40, 58, 76, 82, 98】
第 8 次排序 4, 24, 【 33, 35, 37, 40, 58, 76, 82, 98】
第 9 次排序 4, 【 24, 33, 35, 37, 40, 58, 76, 82, 98】
排序后 4, 24, 33, 35, 37, 40, 58, 76, 82, 98
OC代码实现:
- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSMutableArray *values = @[@37,@33,@24,@4,@98,@76,@82,@58,@35,@40].mutableCopy;
    NSLog(@"排序前: %@", values);
    
    [self bubbleSort:values];
    NSLog(@"排序后: %@", values);
}


- (void)bubbleSort:(NSMutableArray *)values {
    for (int i=0; i<values.count - 1; i++) {
        for (int j=0; j<values.count - i - 1; j++) {
            NSNumber *jValue = values[j];
            NSNumber *jUpValue = values[j+1];
            if(jValue.integerValue > jUpValue.integerValue){
                [values exchangeObjectAtIndex:j withObjectAtIndex:j + 1];
            }
        }
        NSLog(@"第 %d 次排序: %@", i+1, values);
    }
}

从上面列表来看,第一次排序完成最大值98浮出,第二次排序82,98浮出。就像气泡一样一个一个浮出,到最后排序完成。可以看出,冒泡排序的效率很低,平均与最快的时间复杂度都是O(n2)。
其实上面的排序已经使用了右端左移的方法来改进单纯的冒泡排序了。单纯的冒泡排序代码如下:

- (void)lowBubbleSort:(NSMutableArray *)values {
    for (int i=0; i<values.count; i++) {
        for (int j=i; j<values.count; j++) {
            NSNumber *jValue = values[j];
            NSNumber *iValue = values[i];
            if(iValue.integerValue > jValue.integerValue){
                [values exchangeObjectAtIndex:i withObjectAtIndex:j];
            }
        }
        NSLog(@"第 %d 次排序: %@", i+1, values);
    }
}

再仔细看表格中打印的排序信息,其实在第三次排序结束后,数组中的元素已经是从小到大有序的了,第四次已经没有进行元素的交换了。所以可以对排序算法再稍加优化,使用flag标记元素下标是否进行交替。代码如下:

- (void)fastBubbleSort:(NSMutableArray *)values {
    BOOL flag = YES;
    for (int i=0; i<values.count - 1 && flag == YES; i++) {
        flag = NO;
        for (int j=0; j<values.count - i - 1; j++) {
            NSNumber *jValue = values[j];
            NSNumber *jUpValue = values[j+1];
            if(jValue.integerValue > jUpValue.integerValue){
                [values exchangeObjectAtIndex:j withObjectAtIndex:j + 1];
                flag = YES;
            }
        }
        NSLog(@"第 %d 次排序: %@", i+1, values);
    }
}

打印的排序信息如下:

排序前 37, 33, 24, 4, 58, 35, 40, 98, 76, 82
第 1 次排序 33, 24, 4, 37, 35, 40, 58, 76, 82, 【98】
第 2 次排序 24, 4, 33, 35, 37, 40, 58, 76, 【82, 98】
第 3 次排序 4, 24, 33, 35, 37, 40, 58, 【76, 82, 98】
第 4 次排序 4, 24, 33, 35, 37, 40, 【58, 76, 82, 98】
排序后 4, 24, 33, 35, 37, 40, 58, 76, 82, 98

以上就是冒泡排序了,还想对冒泡排序继续优化可以见接下来的更新 Shaker 排序法 - 改良的冒泡排序

选择排序:

将排序对象分为两部分,一个是已排序的,一个是未排序的,在未排序的元素中选取最小(大)的元素放入已排序元素的最后一个。还是将上面那组未排序的数组,使用选择排序进行排序。

排序前 37,33,24,4,58,35,40,98,76,82
第 1 次排序 【4】,33,24,37,58,35,40,98,76,82
第 2 次排序 【4,24】,33,37,58,35,40,98,76,82
第 3 次排序 【4,24,33】,37,58,35,40,98,76,82
第 4 次排序 【4,24,33,35】,58,37,40,98,76,82
第 5 次排序 【4,24,33,35,37】,58,40,98,76,82
第 6 次排序 【4,24,33,35,37,40】,58,98,76,82
第 7 次排序 【4,24,33,35,37,40,58】,98,76,82
第 8 次排序 【4,24,33,35,37,40,58,76】,98,82
第 9 次排序 【4,24,33,35,37,40,58,76,82】,98
排序后 4,24,33,35,37,40,58,76,82,98
OC代码实现
- (void)selectSort:(NSMutableArray *)values {
    for (int i=0; i<values.count - 1; i++) {
        NSInteger index = i;
        for (int j=i; j<values.count; j++) {
            NSNumber *indexValue = values[index];
            NSNumber *jValue = values[j];
            
            if(indexValue.integerValue > jValue.integerValue){
                index = j;
            }
        }
        [values exchangeObjectAtIndex:i withObjectAtIndex:index];
        NSLog(@"第 %d 次排序: %@", i+1, values);
    }
}

插入排序

插入排序也是将排序对象分为两部分,一般将第一个元素作为一部分,然后将后面的元素依次插入第一部分的合适位置,直到排序完成。排序过程看下面表格:

排序前 37,33,24,4,58,35,40,98,76,82
第 1 次排序 【33,37】,24,4,58,35,40,98,76,82
第 2 次排序 【24,33,37】,4,58,35,40,98,76,82
第 3 次排序 【4,24,33,37】,58,35,40,98,76,82
第 4 次排序 【4,24,33,37,58】,35,40,98,76,82
第 5 次排序 【4,24,33,35,37,58】,40,98,76,82
第 6 次排序 【4,24,33,35,37,40,58】,98,76,82
第 7 次排序 【4,24,33,35,37,40,58,98】,76,82
第 8 次排序 【4,24,33,35,37,40,58,76,98】,82
第 9 次排序 【4,24,33,35,37,40,58,76,82,98】
排序后 4,24,33,35,37,40,58,76,82,98
OC代码实现
- (void)insertSort:(NSMutableArray *)values {
    for (int i=1; i < values.count; i++) {
        id iValue = values[i];
        int j = i-1;
        for (j=i-1; j >= 0 && iValue < values[j]; j--) {
            [values exchangeObjectAtIndex:j+1 withObjectAtIndex:j];
        }
        [values replaceObjectAtIndex:j+1 withObject:iValue];
        NSLog(@"第 %d 次排序: %@", i, values);
    }
}

总结:选择、插入、冒泡排序算法时间复杂度都是O(n2)。是比较容易理解的排序算法,但是效率不高。接下来会持续更新“Shell 排序法 - 改良的插入排序”、 “Shaker 排序法 - 改良的气泡排序”
demo github地址

相关文章

  • 选择、插入、冒泡排序算法解法及实现

    冒泡排序: 首先是最熟悉常见的冒泡排序。顾名思义,就像气泡一样,依次将最大(小)值往上浮,直到适当的位置为止。下面...

  • 排序算法详细代码实现

    算法分类 算法时间复杂度 选择排序 插入排序 C++实现 Python实现 冒泡排序 Python实现 归并排序 ...

  • 图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序

    图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序 图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序

  • OC 中实现常用的算法

    #在OC中实现常用的算法(冒泡,选择,快速,插入) ## 1.冒泡排序 - (void)viewDidLoad {...

  • python 排序算法

    文章概述 介绍各大常用经典的排序算法和效率,以及python实现常用算法(冒泡排序,选择排序,快速排序,插入排序)...

  • 数据结构&算法(一)

    一、Java实现快速排序算法 二、Java实现折半插入排序算法 三、Java实现冒泡排序算法

  • 排序一:冒泡、插入、选择

    文章结构 概述 冒泡排序 插入排序 选择排序 1. 概述 常见的排序算法有:冒泡排序、插入排序、选择排序、归并排序...

  • 排序算法

    排序算法 排序是最基本的算法之一,常见的排序算法有插入排序、希尔排序、选择排序、冒泡排序、堆排序、归并排序及快速排...

  • 算法学习之简单排序

    简单排序 简单排序有三种, 冒泡排序,选择排序,插入排序 冒泡排序 冒泡排序是一种易于实现的排序算法, 以升序为例...

  • JavaScript实现排序算法

    实现了冒泡,选择,插入,快排,希尔,归并 冒泡排序 选择排序 插入排序 快速排序 希尔排序 归并排序

网友评论

    本文标题:选择、插入、冒泡排序算法解法及实现

    本文链接:https://www.haomeiwen.com/subject/qphlqftx.html