冒泡排序算法顾名思义,通过每一次排序算法以后,最大的泡泡(数)会飘到最上面,第二次排序以后,第二大的泡泡(数)飘到倒数第二的位置 ..... 以此类推,直至完成从小到大的排序。算法
冒泡排序原理:优化
- 比较相邻的元素。若是第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做一样的工做,从开始第一对到结尾的最后一对。这步作完后,最后的元素会是最大的数。
- 针对全部的元素重复以上的步骤,除了最后一个。
- 持续每次对愈来愈少的元素重复上面的步骤,直到没有任何一对数字须要比较。
用图片表示冒泡排序的过程更直观:code
依照冒泡排序的概念能够方便的写出排序的实现:排序
- (void)bubbleSort:(NSMutableArray *)arr { int count = 0; int cycleCount = 0; for (int i = 0; i<arr.count-1; i++) { cycleCount += 1; // 每次循环都不须要比较最后一个,倒数第二个,倒数第三个... 因此二层循环最好减去已经排好序的数 for (int j = 0; j<arr.count-i-1; j++) { cycleCount += 1; if ([arr[j] integerValue] > [arr[j+1] integerValue]) { NSInteger temp = [arr[j] integerValue]; arr[j] = arr[j+1]; arr[j+1] = @(temp); count += 1; } } } NSLog(@"交换次数-->%@",@(count)); NSLog(@"循环次数-->%@",@(cycleCount)); NSLog(@"%@",arr); }
上面的方式是最原始的排序,再次基础上能够对冒泡排序进行优化 。图片
冒泡排序的主要操做就是不断的循环比较而后交换两个大小不一样的数的位置。 若是要正确的排序交换的次数确定是固定的,这个是不能减小的,那就从循环比较上进行优化 。 table
用一个变量进行记录,记录在一次循环中是否发生了交换,若是没有则说明这个序列已是有序的了,则退出循环。class
- (void)bubbleSort:(NSMutableArray *)arr { int count = 0; int cycleCount = 0; for (int i = 0; i<arr.count-1; i++) { cycleCount += 1; finished = YES; for (int j = 0; j<arr.count-i-1; j++) { cycleCount += 1; if ([arr[j] integerValue] > [arr[j+1] integerValue]) { NSInteger temp = [arr[j] integerValue]; arr[j] = arr[j+1]; arr[j+1] = @(temp); finished = NO; count += 1; } } if (finished) break; } NSLog(@"----交换次数为%@",@(count)); NSLog(@"----循环次数为%@",@(cycleCount)); NSLog(@"%@",arr); }
仔细研究冒泡排序的原理能够发现,还能够再次基础上进行优化。 记录每一次内层循环排序最后发生位置交换的位置K,这个位置以后的都已是有序的了,下次排序内层循环只须要排序前 0--K 个数便可 。基础
- (void)bubbleSort3:(NSMutableArray *)arr { int count = 0; int cycleCount = 0; int pos = (int)arr.count-1; for (int i = 0; i<arr.count-1; i++) { finished = YES; cycleCount += 1; int currentPos = 0; // 从上一次发生交换的位置开始循环 for (int j = 0; j<pos; j++) { cycleCount += 1; if ([arr[j] integerValue] > [arr[j+1] integerValue]) { NSInteger temp = [arr[j] integerValue]; arr[j] = arr[j+1]; arr[j+1] = @(temp); count += 1; // 记录发生交换的位置 currentPos = j; finished = NO; } } pos = currentPos; if (finished) break; } NSLog(@"交换次数-->%@",@(count)); NSLog(@"循环次数-->%@",@(cycleCount)); NSLog(@"%@",arr); }
时间复杂度:变量
冒泡排序须要进行两层循环,最坏的状况是:序列正好是倒序的,这种状况是O(n²),最好的状况是:序列正好的是正序的,这种状况是:O(n) .平均时间复杂度是O(n²)。原理
因为时间复杂度是平方级的,因此冒泡排序通常适用于小序列排序 。序列小(如:长度在20个之内)的状况下冒泡排序是比快排的速度还要快的。