目标
将一组数,按从小到大进行排序
如:
输入:3,4,1,43,67,65,5;
输出:1,3,4,5,43,65,67;
分析
第一步,找到数组中最小值项,然后将此项放到最左侧;
第二步,找到数组中的次最小值项,然后将些项放在倒数第二侧;
...
由上面的步骤,最大的数会慢慢地移动到最右侧,这个过程就是像是大大小小的泡泡依次排序一样,越大的泡泡,越排在最右侧。这个方法也被称为冒泡排序
。
并可以得出以下信息
第一步的操作,可以看成这个数组中的最小值一直移到最左侧,第二步的操作,是除了已知的最小值的数组,重新找到最小数移到最左侧。
假如原数组元素个为N,则要执行的N-1步才能完成操作。
第一步的操作如何实现呢?从数组尾部开始两两比较大小,将小的值放到左侧
。
在此可以判断需要两个操作比较大小
操作
int cmp (int *a, int *b);
数值交换
操作
void swap(int *a, int *b);
这样的比较操作,在这一步中需要多少次呢?
剩余未排序元素个数
unsort_meb - 1
cmp_count = unsort_meb - 1;
unsort_meb初始值为一开始的元素个数nmeb
unsort_meb = nmeb;
至此,上面的操作可以表述为
unsort_meb = nmeb;
cmp_count = unsort_meb - 1;
int index = nmeb -1; //获得数据最右侧的下标,开始从最右侧开始比较
for (int i = 0; i < cmp_count; i ++)
{
if(cmp(&data[index - 1], &data[index]) > 0)
swap(&data[index - 1], &data[index]);
index --;
}
unsort_meb --;
第二步,也是从最右侧开始交换,由于完成了第一步,所以unsort_meb-1, 次数比上一次少了一次。
cmp_count = unsort_meb - 1;
int index = nmeb -1; //获得数据最右侧的下标,开始从最右侧开始比较
for (int i = 0; i < cmp_count; i ++)
if(cmp(&data[index - 1], &data[index]) > 0)
swap(&data[index - 1], &data[index]);
...
到了最后,unsort_meb = 1,就完成了排序
由此可以得到以下代码:
void bubble_sort(int data[], const int nmeb)
{
for (int unsort_meb = nmeb; unsort_meb > 1; unsort_meb --)
{
int index = nmeb -1;
for (int cmp_count = unsort_meb - 1; cmp_count > 0; cmp_count --)
if(cmp(&data[index - 1], &data[index]) > 0)
swap(&data[index - 1], &data[index]);
}
}
本例的整体代码如下:
#include <stdio.h>
int cmp(const int *a, const int *b)
{
return (*a - *b);
}
void swap(int *a, int *b)
{
int dummy;
dummy = *b;
*b = *a;
*a = dummy;
}
//从后向前排
void bubble_sort(int data[], const int nmeb)
{
for (int unsort_count = nmeb; unsort_count > 1; unsort_count--)
{
int index = nmeb - 1; //比较时的初始索引
for (int cmp_count = unsort_count - 1; cmp_count > 0; cmp_count--)
{
if (cmp(&data[index - 1], &data[index]) > 0)
{
swap(&data[index - 1], &data[index]);
}
index--;
}
}
}
void show_array(int data[], int nmeb)
{
for (size_t i = 0; i < nmeb; i++)
{
printf("%d ", data[i]);
}
printf("\n");
}
int main(void)
{
int test[] = {3, 4, 1, 43, 67, 65, 5};
show_array(test, sizeof(test) / sizeof(test[0]));
bubble_sort(test, sizeof(test) / sizeof(test[0]));
show_array(test, sizeof(test) / sizeof(test[0]));
return 0;
}