和选择排序同样,冒泡排序也是经典的排序算法,很多入门课程讲的第一个算法就是它。所谓冒泡,指排序过程中元素的移动方式就像上浮的气泡,非常形象。
算法思想:
1、从后向前遍历,把当前元素与其前驱元素排序,一轮后可以使最小(大)的元素移动到表头。
2、对于包含n个元素的表,重复上述过程n次即可达到有序。
示例代码:
#define SWAP(A, B) do{(A) ^= (B); (B) ^= (A); (A) ^= (B);} while(0)
enum {FALSE, TRUE};
void _bubble_sort(int array[], int left, int right) {
int i, j;
int unshift; //判断遍历时是否有元素移位的标志位
for(i = 0; i < right; i++) {
unshift = TRUE;
for(j = right; j > i; j--) {
if(array[j - 1] > array[j]) {
SWAP(array[j - 1], array[j]);
unshift = FALSE;
}
}
if(unshift == TRUE) { //若遍历一轮后没有发生移位说明已经达到有序
break;
}
}
}
void bubble_sort(int array[], int len) {
_bubble_sort(array, 0, len - 1);
}
复杂度分析:
内部循环执行了n-i次(i = 1, 2, 3,... , n - 1),外部循环执行了n次,总共进行了n*(n - 1)/2次比较,时间复杂度为O(n^2),在最坏情况下需要移动元素n*(n-1)/2次。另外,由于不需要额外空间,空间复杂度为O(1)。
重要性质:
1、若相邻元素相等则不会进行交换,故为稳定排序
2、可以通过一轮遍历中是否发生元素移位判断是否已经达到有序,在原始序列部分有序时可以提高效率