冒泡算法和选择排序一样,也属于蛮力算法。简单描述为:在一个长度为n的数列中,相邻的数字之间两两比较,如果两个数字的大小排序不符合排序要求(降序或升序),则交换这两个数字的位置,依次比较,直到最后两个数字之间比较结束,这样最大的数字放到了列表的最后的位置,然后再从[0,n-2]个数中进行比较,第二大数字最后放到数列的倒数第二个位置...重复这样的操作n-1次,排序完成。简单记忆为:两两比较,越比越少,重复n-1次。
2.实例
使用冒泡排序将下列数列按升序排列
5 2 9 1 4 3
第一次排序
5和2不符合升序排列,互换后数列如下:
2 5 9 1 4 3
5和9符合升序排序,位置不变,9和1不符合升序排序,位置互换,互换后数列如下:
2 5 1 9 4 3
9和4不符合升序排序,位置互换,互换后数列如下:
2 5 1 4 9 3
9和3的位置不符合升序排序,位置互换,互换后数列如下:
2 5 1 4 3 9
第一次排序结束,最大数9放到了最终位置。
第二次排序
2和5符合升序排列,位置不变,5和1不符合升序排列,位置互换,互换后数列如下:
2 1 5 4 3 9
5和4不符合升序排列,位置互换,互换后数列如下:
2 1 4 5 3 9
5和3不符合升序排列,位置互换,互换后数列如下:
2 1 4 3 5 9
第二次排序结束,第二大数5放到了最终位置。
第三次排序
2和1不符合升序排序,互换位置,互换后数列如下:
1 2 4 3 5 9
2和4符合升序排列,位置不变,4和3不符合升序排列,位置互换,互换后数列如下:
1 2 3 4 5 9
4和5符合升序排列,位置不变,第三次排序结束,第三大数4放到了最终位置。
第四次排序
数列中所有的数两两比较,都符合升序排序,没有需要互换位置的。
1 2 3 4 5 9
第四次排序结束,第四大数3放到了最终位置。(本排序中3在第三次排序中就已经放到了最终位置)
第五次排序
数列中所有的数两两比较,都符合升序排序,没有需要互换位置的。
1 2 3 4 5 9
第五次排序结束,第五大数2放到了最终位置,前5个数位置已经排好,那么第六个数1的位置也就确定了,因此排序终于结束了。
在上面的实例中我们发现,排序在第三次循环中就已经排好了,但是还是需要继续循环,直到第5次(n-1)排序才结束,这样多做了两次没有意义的循环,因此该算法还有可以优化的地方,在下面的代码中会贴出普通的冒泡排序和优化后的冒泡排序代码。
3.代码
void bubble_sort::bubble_sort_with_array(int nums[], int num_count)
{
//we need loop n-1 times
for(unsigned int i=0;i<num_count-1;i++)
{
for(unsigned int j=0;j<num_count-i-1;j++)
{
if(nums[j]>nums[j+1])
{
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
}
优化代码:
void bubble_sort::bubble_sort_optimized_with_array(int nums[], int num_count)
{
int exchanged = 0;
for(unsigned int i=0;i<num_count-1;i++)
{
exchanged = 0;
for(unsigned int j=0;j<num_count-i-1;j++)
{
if(nums[j]>nums[j+1])
{
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
exchanged = 1;
}
}
if(0 == exchanged)
break;
}
}
4.算法分析