排序之冒泡排序
冒泡排序概念
两两比较相邻记录的关键字,如果反序则交换,直到没有反序记录为止。
最简单的冒泡排序实现
交换排序:每一个数字都与它后面的每一个数字比较。

这种算法效率很低,前面排好的数字没有作用,3作为一个很小的数字第一次时,反而被排到最后一个位置。
代码:
#include "stdio.h"
#define MAXSIZE 10
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int length;
} SqList;
//交换传入的值
void swap(SqList *L, int i, int j)
{
ElemType temp;
temp = L->data[i];
L->data[i] = L->data[j];
L->data[j] = temp;
}
//初级版冒泡排序
void BubbleSort(SqList *L)
{
int i, j;
for (i = 0; i < L->length; i++)
{
for (j = 0; j < L->length; j++)
{
if (L->data[i] > L->data[j])
{
swap(L, i, j);
}
}
}
}
int main()
{
SqList list = {{3, 5, 7, 4, 10, 0, 0, 0, 0, 0}, 5};
BubbleSort(&list);
for (int i = 0; i < list.length; i++)
{
SqList *L = &list;
printf("%d ", L->data[i]);
}
}
正宗的冒泡排序

与第一种比优点:在一次循环中,如上图,不仅把最小值1放到了第一个位置,还把3提到了前面。怎么减少循环呢?详情看下面的优化
#include "stdio.h"
#define MAXSIZE 10
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int length;
} SqList;
//交换传入的值
void swap(SqList *L, int i, int j)
{
ElemType temp;
temp = L->data[i];
L->data[i] = L->data[j];
L->data[j] = temp;
}
//冒泡排序(从小到大)
void BubbleSort(SqList *L, int *count)
{
int i, j, k = 0;
for (i = 0; i < L->length; i++)//i代表前面已经排好序的数字的索引
{
for (j = L->length - 1 - 1; j >= i; j--) //j从后往前循环(j要等于i,是因为j+1个数与j个数比)
{
if (L->data[j] > L->data[j + 1]) //前一个大于后一个
{
swap(L, j, j + 1);
k++;
}
}
}
*count = k;
}
int main()
{
int count = 0;
SqList list = {{7, 1, 10, 4, 5, 3, 0, 0, 0, 0}, 6};
BubbleSort(&list, &count);
for (int i = 0; i < list.length; i++)
{
SqList *L = &list;
printf("%d ", L->data[i]);
}
printf("change %d\n", count);//交换了9次
}
冒泡排序的优化

根据上图,代码如下
避免有序的情况下进行循环判断
#include "stdio.h"
#define MAXSIZE 25
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int length;
} SqList;
//交换传入的值
void swap(SqList *L, int i, int j)
{
ElemType temp;
temp = L->data[i];
L->data[i] = L->data[j];
L->data[j] = temp;
}
//优化冒泡排序(如果内层循环检测没有需要交换的数据,即排序已经成功了,外层循环就不用再循环了)
void BubbleSort(SqList *L, int *count)
{
int i, j, k = 0;
Status flag=TRUE;//用来标记是否还有需要交换的数据
for (i = 0; i < L->length&&flag; i++) //flag为FALSE则退出循环
{
flag=FALSE;//初始flag为FALSE
for (j = L->length - 1 - 1; j >= i; j--)
{
k++;
if (L->data[j] > L->data[j + 1])
{
swap(L, j, j + 1);
flag=TRUE;//如果有数据交换,则flag为true
}
}
}
*count = k;
}
int main()
{
int count = 0;
SqList list = {{28, 77, 66, 91, 29, 48, 39, 49, 80, 3, 41, 26, 23, 59, 7, 60, 5, 77, 16, 65}, 20};
BubbleSort(&list, &count);
for (int i = 0; i < list.length; i++)
{
SqList *L = &list;
printf("%d ", L->data[i]);
}
printf("loop %d\n", count); //循环了187次
}
时间复杂度分析

相同元素的前后顺序并没有改变,冒泡排序是一种稳定排序算法

浙公网安备 33010602011771号