冒泡排序(Bubble Sort): 一種交換排序,它的基本思想是:兩兩比較相鄰的關(guān)鍵字,如果反序則交換,直到?jīng)]有反序的記錄為止。
平實(shí)寫冒泡排序,我都是這么寫的:
- (void)logArray {
NSMutableArray * arr = @[@16,@1,@2,@9,@7,@12,@5,@3,@8,@13,@10].mutableCopy;
for (int i = 0; i < arr.count; i++) {
for (int j = i+1; j < arr.count; j++) {
if ([arr[i] intValue] < [arr[j] intValue]) {
[arr exchangeObjectAtIndex:i withObjectAtIndex:j];
}
}
[self logArr:arr];
}
}
//打印數(shù)組
- (void)logArr:(NSMutableArray * )array {
NSString * str = @"";
for (NSNumber * value in array) {
str = [str stringByAppendingString:[NSString stringWithFormat:@"%zd ",[value integerValue]]];
}
NSLog(@"%@",str);
}
//打印結(jié)果如下
16 1 2 9 7 12 5 3 8 13 10
16 13 1 2 7 9 5 3 8 12 10
16 13 12 1 2 7 5 3 8 9 10
16 13 12 10 1 2 5 3 7 8 9
16 13 12 10 9 1 2 3 5 7 8
16 13 12 10 9 8 1 2 3 5 7
16 13 12 10 9 8 7 1 2 3 5
16 13 12 10 9 8 7 5 1 2 3
16 13 12 10 9 8 7 5 3 1 2
16 13 12 10 9 8 7 5 3 2 1
16 13 12 10 9 8 7 5 3 2 1
查了定義后發(fā)現(xiàn),這不算是標(biāo)準(zhǔn)的冒牌排序算法,因?yàn)樗粷M足“兩兩比較相鄰”的冒泡排序思想,它更應(yīng)該是最最簡(jiǎn)單的交換排序而已。它的思路是讓每個(gè)關(guān)鍵字,都和它后面的一個(gè)關(guān)鍵字比較,如果小則交換。
它應(yīng)該算是最容易寫的排序代碼了,不過(guò)這個(gè)簡(jiǎn)單易懂的代碼是有缺陷的,觀察后發(fā)現(xiàn),每次排序只能確定一個(gè)位置,直到倒數(shù)第二次 末尾的最小值1才顯示到最后,也就是說(shuō),這個(gè)算法的效率是非常低的。
正宗的冒泡排序算法:
- (void)logArrayFunction {
int count = 0;
int forcount = 0;
NSMutableArray * arr = @[@16,@1,@2,@9,@7,@12,@5,@3,@8,@13,@10].mutableCopy;
for (int i = 0; i < arr.count; i++) {
forcount++;
// 依次定位左邊的
for (int j = (int)arr.count-2; j >= i; j--) {
count++;
if ([arr[j] intValue]< [arr[j+1] intValue]) {
[arr exchangeObjectAtIndex:j withObjectAtIndex:j+1];
}
}
[self logArr:arr];
}
NSLog(@"循環(huán)次數(shù):%d",forcount);
NSLog(@"共%d次比較",count);
}
//打印如下
16 13 1 2 9 7 12 5 3 8 10
16 13 12 1 2 9 7 10 5 3 8
16 13 12 10 1 2 9 7 8 5 3
16 13 12 10 9 1 2 8 7 5 3
16 13 12 10 9 8 1 2 7 5 3
16 13 12 10 9 8 7 1 2 5 3
16 13 12 10 9 8 7 5 1 2 3
16 13 12 10 9 8 7 5 3 1 2
16 13 12 10 9 8 7 5 3 2 1
16 13 12 10 9 8 7 5 3 2 1
16 13 12 10 9 8 7 5 3 2 1
循環(huán)次數(shù):11
共55次比較
/// 同樣的道理,先定位右邊:
int count = 0;
int forcount = 0;
NSMutableArray * arr = @[@16,@1,@2,@9,@7,@12,@5,@3,@8,@13,@10].mutableCopy;
for (int i = 0; i < arr.count; i++) {
forcount++;
for (int j = 0; j < arr.count-i-1; j++) {
count++;
if ([arr[j] integerValue] < [arr[j+1] integerValue]) {
[arr exchangeObjectAtIndex:j withObjectAtIndex:j+1];
}
}
[self logArr:arr];
}
NSLog(@"循環(huán)次數(shù):%d",forcount);
NSLog(@"共%d次比較",count);
16 2 9 7 12 5 3 8 13 10 1
16 9 7 12 5 3 8 13 10 2 1
16 9 12 7 5 8 13 10 3 2 1
16 12 9 7 8 13 10 5 3 2 1
16 12 9 8 13 10 7 5 3 2 1
16 12 9 13 10 8 7 5 3 2 1
16 12 13 10 9 8 7 5 3 2 1
16 13 12 10 9 8 7 5 3 2 1
16 13 12 10 9 8 7 5 3 2 1
16 13 12 10 9 8 7 5 3 2 1
16 13 12 10 9 8 7 5 3 2 1
循環(huán)次數(shù):11
共55次比較
冒泡排序的優(yōu)化:
設(shè)想如果待排序的序列是{2,1,3,4,5,6,7,8,9},也就是說(shuō),2和1交換后就屬于正常的排序結(jié)果了,但是之后的大量比較還是大大多余了。所以如果循環(huán)一次后如果沒(méi)有數(shù)據(jù)交換,這就說(shuō)明此序列已經(jīng)有序,不需要再繼續(xù)后面的循環(huán)判斷工作了,為了實(shí)現(xiàn)這一想法,我們需要改進(jìn)下代碼,增加個(gè)BOOL變量flag來(lái)實(shí)現(xiàn)這一算法的改進(jìn)。
- (void)logArrayFunctionNice {
int count = 0;
int forcount = 0;
BOOL flag = YES;
NSMutableArray * arr = @[@16,@1,@2,@9,@7,@12,@5,@3,@8,@13,@10].mutableCopy;
for (int i = 0; i < arr.count && flag; i++) {
forcount++;
flag = NO;
for (int j = (int)arr.count-2; j >= i; j--) {
count++;
if ([arr[j] intValue]< [arr[j+1] intValue]) {
[arr exchangeObjectAtIndex:j withObjectAtIndex:j+1];
flag = YES;
}
}
[self logArr:arr];
}
NSLog(@"循環(huán)次數(shù):%d",forcount);
NSLog(@"共%d次比較",count);
}
//打印
16 13 1 2 9 7 12 5 3 8 10
16 13 12 1 2 9 7 10 5 3 8
16 13 12 10 1 2 9 7 8 5 3
16 13 12 10 9 1 2 8 7 5 3
16 13 12 10 9 8 1 2 7 5 3
16 13 12 10 9 8 7 1 2 5 3
16 13 12 10 9 8 7 5 1 2 3
16 13 12 10 9 8 7 5 3 1 2
16 13 12 10 9 8 7 5 3 2 1
16 13 12 10 9 8 7 5 3 2 1
循環(huán)次數(shù):10
共45次比較
冒泡排序復(fù)雜度分析
分析一下它的時(shí)間復(fù)雜度。當(dāng)最好的情況,也就是要排序的本身就是有序的,那么我們比較次數(shù),根據(jù)最后改進(jìn)的代碼,可以推斷出就是n-1次的比較,沒(méi)有數(shù)據(jù)交換,時(shí)間復(fù)雜度為O(n),當(dāng)最壞的情況,即待排序表示逆序的情況,此時(shí)需要比較1+2+3+...+(n-1) = n(n-1)/2次,并作等數(shù)量級(jí)的記錄移動(dòng),因此,總的時(shí)間復(fù)雜度為O(n2)。
備注:
時(shí)間性能 = 對(duì)比次數(shù) + 是否移動(dòng)
時(shí)間復(fù)雜度表: