冒泡排序(Bubble Sort)
假设待排序表长为n,从后往前(或从前往后)两两比较相邻元素的值,若为逆序(即A[i-1]>A[i]),则交换它们,直到序列比较完。我们称它为一趟冒泡,结果将最小的元素交换到待排序列的第一个位置。下一趟冒泡时,前一趟确定的最小元素不再参与比较,待排序列减少一个元素,每趟冒泡的结果把序列中的最小元素放到了序列的最终位置,……,这样最多做n-1趟冒泡就能把所有元素排好序。
算法原理
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 每对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一步,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
性能分析
空间复杂度:交换时开辟了存储空间来存储中间变量,所以空间复杂度为O(1)
时间复杂度:该算法基本操作是在于交换两个数据。
最坏情况下,初始序列就是逆序的,那么对于外层每一次循环,内层循环始终成立,外层循环i从0执行到n-1,第i次内层循环执行次数为n-1-i,所以一共执行?=0?−1?−1−ⅈ∑129_(i=0)^(n-1)▒n-1-ⅈ=n(n-1)/2 所以最坏情况下时间复杂度为O(n2)。
最好情况下,初始序列就是顺序的,内层循环if条件始终不成立,所以内层执行n-1次后结束,所以时间复杂度为O(n)
稳定性:当两个关键字相等,if判断条件不成立,所以不会发生数据移动。所以是稳定的。
代码实现
#include <stdio.h>
#define MAXSIZE 8
typedef int KeyType; //定义关键字类型
typedef struct //记录类型
{
KeyType key; //关键字项
} ElemType; //排序的记录类型定义
/*
冒泡排序
参数说明:
arr:传入要排序的数组
n:数组的大小
*/
void ShellSort(ElemType A[] , int n)
{
int i,j,k=0;
int flag=0;
//用冒泡排序法将序列A中的元素按从小到大排序
for(i=0;i<n-1;i++){
flag=0;//表示本趟冒泡是否发生交换的标志
for(j=n-1;j>i;j--){
if(A[j-1].key>A[j].key){
//swap(A[j-1],A[j]);//交换
k=A[j-1].key;
A[j-1].key=A[j].key;
A[j].key=k;
flag=1;
}
if(flag=0)
return;
}
}
}
int main()
{
ElemType A[MAXSIZE] = {0};
int arr[] = {0,6,5,12,3,42,1,9};
int i;
printf("-----------------冒泡排序----------------\n" );
printf("排序前:");
for(i = 1; i < MAXSIZE; i++)
{
A[i].key = arr[i];
printf("A[%d].key = %d\t" , i , A[i].key);
}
printf("\n");
//插入排序
ShellSort(A, MAXSIZE);
printf("排序后:");
for(i = 1; i < MAXSIZE; i++)
{
printf("A[%d].key = %d\t" , i , A[i].key);
}
return 0;
}