在开发中,对一组数据进行有序地排列是经常需要做的事情,所以掌握几种甚至更多的排序算法是绝对有必要的
本文章介绍的是排序算法中较简单的一种算法:冒泡排序
题外话:在深入学习更多排序算法后和在实际使用情况中,冒泡排序的使用还是极少的。它适合数据规模很小的时候,而且它的效率也比较低,但是作为入门的排序算法,还是值得学习的
先尝试用最简单的想法去实现排序,以此来比较学习冒泡排序
问题:设有一数组,其大小为10个元素(int str[10])数组内的数据是无序。现在要求我们通过编程将这个无序的数组变成一个从小到大排序的数组(从下标为0开始)
思路:按照题目的要求,毫无疑问,正确的结果应该就像这样: 1 2 3 4 5 6 7 8 9 10 要做到这样,最简单和最直接想到的方法就是进行对比交换。
- 首先,把10个数里最小的个数放到下标为0的位置上(str[0])
- 通过将下标为0的数(str[0])与剩下其余9个数进行对比交换(将较少者放置在下标为0的位置上),就可以得到这10个数最小的那个
- 10个数最小的那位确定后,接下来就要找剩下9个数最小的那个。
- 因为已经确定出一个最小的数,所以就不要动str[0],直接从str[1]开始,与剩下的8个数对比交换,找出9个数中最小的那位放到下标为1(str[1])的位置上
- 继续按照这个思路就可以将这十个数变成有序的(从小到大)的数组
代码:
#include <stdio.h>
void swap(int *a, int *b); //交换两个数
int main()
{
int str[10];
int i, j;
//初始化数组为10 9 8 7 6 5 4 3 2 1
for (i = 0; i < 10; i++)
{
str[i] = 10 - i;
}
//排序,从a[0]开始排,从小到大
for (i = 0; i < 10; i++)
{
for (j = i + 1; j < 10; j++)
{
if (str[i] > str[j])
{
swap(&str[i], &str[j]);
}
}
}
//将十个数输出
for (i = 0; i < 10; i++)
printf("%d\n", str[i]);
return 0;
}
void swap(int *a, int *b)
{
int c;
c = *a;
*a = *b;
*b = c;
}
这个方法是比较容易想到的实现方法。但
存在不足:就是本来位于前面的较小数被交换到后面
演示: 开始:
9 4 5 6 8 3 2 7 10 1 (下标从左到右分别是0~9)按照上面的程序进行对比交换 第一次:
4 9 5 6 8 3 2 7 10 1 第二次:
4 9 5 6 8 3 2 7 10 1 。。。:(没有交换) 第五次:
3 9 5 6 8 4 2 7 10 1 第六次:
2 9 5 6 8 3 4 7 10 1 。。。:(没有交换) 第十次:
1 9 5 6 8 3 4 7 10 2
可以看出,原来较小的数是在前面的,经过一轮的交换后放到后面了
那么怎样解决这个不足呢?可以使用
冒泡排序
什么是冒泡排序呢? 你可以这样理解:(从小到大排序)存在10个不同大小的气泡,由底至上地把较少的气泡逐步地向上升,这样经过遍历一次后,最小的气泡就会被上升到顶(下标为0),然后再从底至上地这样升,循环直至十个气泡大小有序。 在
冒泡排序中,
最重要的思想是两两比较,将两者较少的升上去
冒泡排序最坏情况的时间复杂度是O(n²)
代码:
#include <stdio.h>
void swap(int *a, int *b);
int main()
{
int array[10] = {15, 225, 34, 42, 52, 6, 7856, 865, 954, 10};
int i, j;
for (i = 0; i < 10; i++)
{
//每一次由底至上地上升
for (j = 9; j > i; j--)
{
if (array[j] < array[j-1])
{
swap(&array[j], &array[j-1]);
}
}
}
for (i = 0; i < 10; i++)
{
printf("%d\n", array[i]);
}
return 0;
}
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
冒泡排序算法只会将较少的逐步向上推,不会造成文章前面所说的不足,这里就不给予演示。 有些追求完美的人就会思考,冒泡排序能不能优化呢?
答案是能的。如何优化的文章在
这里。