冒泡排序主要思路是:
通过交换使相邻的两个数变成小数在前大数在后,这样每次遍历后,最大的数就到最后面了。重复 N 次即可以使数组有序。
冒泡排序是非常容易理解和实现,以从小到大排序举例: 设数组长度为N。比较相邻的前后二个数据,如果前面数据大于后面的数据,就将二个数据交换。这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就到数组第N-1个位置。N=N-1,如果N不为0就重复前面步骤,否则排序完成。
时间复杂程度:O(N^2)
代码实现
#include<stdio.h>
void bubbleSort(int* arr, int n)
{
int temp;
for (int i = 0; i < n; i++)
{
for (int j = 1; j < n - i; j++)
{
if (arr[j - 1] > arr[j])
{
temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
}
}
}
}
void print(int* arr, int n)
{
for(int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int n = 10;
int arr[10] = {5,7,3,4,9,2,1,8,6,0};
print(arr, n);
bubbleSort(arr, n);
print(arr, n);
return 0;
}
冒泡排序改进 1:
在某次遍历中如果没有数据交换,说明整个数组已经有序。因此通过设置标志位来记录此次遍历有无数据交换就可以判断是否要继续循环。
#include<stdio.h>
#include <stdbool.h>
#define Swap(x,y) {int temp = x; x = y; y = temp;}
void bubbleSort(int* arr, int n)
{
int j, k;
bool flag;
k = n;
flag = true;
while (flag)
{
flag = false;
for (j = 1; j < k; j++)
if (arr[j - 1] > arr[j])
{
Swap(arr[j - 1], arr[j]);
flag = true;
}
k--;
}
}
void print(int* arr, int n)
{
for(int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int n = 10;
int arr[10] = {5,7,3,4,9,2,1,8,6,0};
print(arr, n);
bubbleSort(arr, n);
print(arr, n);
return 0;
}
冒泡排序改进 2:
记录某次遍历时最后发生数据交换的位置,这个位置之后的数据显然已经有序了。因此通过记录最后发生数据交换的位置就可以确定下次循环的范围了。
#include<stdio.h>
#define Swap(x,y) {int temp = x; x = y; y = temp;}
void bubbleSort(int* arr, int n)
{
int j, k;
int flag;
flag = n;
while (flag > 0)
{
k = flag;
flag = 0;
for (j = 1; j < k; j++)
if (arr[j - 1] > arr[j])
{
Swap(arr[j - 1], arr[j]);
flag = j;
}
}
}
void print(int* arr, int n)
{
for(int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int n = 10;
int arr[10] = {5,7,3,4,9,2,1,8,6,0};
print(arr, n);
bubbleSort(arr, n);
print(arr, n);
return 0;
}
总的来说冒泡排序是一种效率低下的排序方法,在数据规模很小时,可以采用。当数据规模比较大时,最好用其它排序方法。