冒泡排序虽然简单,但是之前没有细细体会过程,经常写错循环条件。做个笔记,以防遗忘。
将所有元素的从第一个到最后一个, 相邻的两个元素之间全部两两比较一次,逆序则交换,称为一趟冒泡过程。
首先,明白这样的事实:
1. N个元素, 相邻两个元素之间两两比较只需N-1次就可以选出最大值。
2. N个元素, 第1趟冒泡, 两两比较N-1次,选出了N个元素中最大的元素(正序中最后一个位置)。第2趟冒泡,需要在N-1个元素中两两比较N-2次,选出最大的元素(也就是N个元素中第二大的元素, 正序中倒数第2个位置)。由此推出第k趟需要比较N-1-k次来选择出N-k个元素中最大的元素(也就是N个元素中第k大的元素, 正序中倒数第k个位置)。
冒泡排序的过程就是从一个元素开始,相邻的元素之间两两比较,逆序则交换。每一趟冒泡结束后,最后一个元素就选是当前序列中最大的元素, 最后一个元素不会参与下一次冒泡过程, 这样下一次参加冒泡过程的元素个数每次减少1,直到最后参加冒泡的只有第1个个元素,这样 N个元素就变成了正序。
冒泡排序的特点是:
1.N个元素必定会比较 N*(N+1)/2次。
2.N个元素如果是正序,则比较N*(N+1)/2次, 不用交换。
3. N个元素如果是逆序, 则比较N*(N+1)/2次, 交换N*(N+1)/2次
冒泡排序中,可以设置一个标志, 如果第一趟冒泡过程中, 没有发生交换, 则说明是正序, 省下了后续无用的比较。
明白过程后, 就不会写错循环条件。
常用的冒泡排序代码中, 一般的形式就一下2种:
1.每趟选出最大的
void bubble_sort(int* p, int n)
{
int i, j;
for(i=0; i<n-1; ++i)
{
for(j=0; j<n-1-i; ++j)
{
if(p[j+1] < p[j])
{
swap(&p[j+1], &p[j]);
}
}
}
}
2.每趟选出最小的
void bubble_sort(int* p, int n)
{
int i, j;
for(i=0; i<n-1; ++i)
{
for(j=n-1; j>i; --j)
{
if(p[j-1] > p[j])
{
swap(&p[j-1], &p[j]);
}
}
}
}