前言:
首先由于C中没有直接进行两数交换的函数,而排序算法多要用到,因此我们先写出交换两数位置的函数swap(),思路以及实现很简单,不赘述
void swap(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
冒泡排序就像名称一样是冒泡一样进行排列,从头开始依次比较每两个相邻的元素,并把我们要求的元素调动位置。在数据量较大的情况下比较次数极多,达到 n^2 数量级
空间复杂度为 O(1),没有开辟额外的内存空间
时间复杂度O(n^2)
原理:
首先考虑我们的排序是升序还是降序,如果是升序,就是每一次冒泡将剩下的数列中最大的数挪到可以放的最后一位,为什么要说剩下的数列,因为每次冒泡过程都会减少数列的一个空间,换句话说每次冒泡都会确定一个数的合理位置(数组的最后)。
降序同理。
考虑到我们需要两个下标进行比较,因此设定双层for循环是比较普遍的思路,唯一需要注意的是两层for循环的结束条件不一样:
假设有数组a[N],外层用 i 控制,内层用 j 控制:
外层for循环需要遍历a[ 0 ]---a[ N - 1 ],因为最后一个数没有比较的必要了,直接就确定了位置;
内层for循环需要比较从a[ 0 ]---a[ N - 1 - i ],因为如我上面所说,每次外层循环都会确定一个数的合理位置,所以我们每下一次内层比较都需要剔除外层所确定的数;
下面是实际代码:
void BubbleSort(int *a,int length)
{
int temp = 0;
for (int i = 0; i < length - 1; i++)
{
for (int j = 0; j < length - i - 1; j++)
{
if (a[j] > a[j + 1])//升序是>;降序是<
{
swap(&a[j],&a[j+1]);
}
}
}
}
测试用代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 30
void generate_random_number(int *a ,int left_limit,int right_limit)//左右闭区间
{
srand((void*)time(NULL));
int gap = right_limit - left_limit + 1;
for (int i = 0; i < N; i++)
a[i] = rand() % gap + left_limit;
printf("生成随机数列:\n");
for (int i = 0; i < N; i++)
printf("%d ", a[i]);
printf("\n");
}
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void BubbleSort(int *a,int length)
{
int temp = 0;
for (int i = 0; i < length - 1; i++)
{
for (int j = 0; j < length - i - 1; j++)
{
if (a[j] > a[j + 1])//升序是>;降序是<
{
swap(&a[j], &a[j+1]);
}
}
}
}
int main()
{
int arr[N + 10] = { 0 };
generate_random_number(arr,0,1024);
BubbleSort(arr,N);
printf("排序后数列:\n");
for (int i = 0; i < N; i++)
printf("%d ", arr[i]);
printf("\n");
}
测试结果:
至此,BubbleSort完成。