冒泡排序的基本思想
设数组a中存放了n个数据元素,循环进行n-1趟如下的排序过程:第1趟时,依次比较相邻两个数据元素a[i].key和a[i+1].key(i=0, 1, 2, …, n-2),若为逆序,即a[i].key>a[i+1].key,则交换两个数据元素,否则不交换,这样数值最大的数据元素将被放置在a[n-1]中;第2趟时,数据元素个数减1,即数据元素个数为n-1,操作方法和第1趟的类似,这样整个n个数据元素集合中数值次大的数据元素将被放置在a[n-2]中;当第n-1趟结束时,整个n个数据元素集合中次小的数据元素将被放置在a[1]中,a[0]中放置了最小的数据元素。
算法如下:
void BubbleSort(DataType a[], int n){//用冒泡排序对a[]进行排序
int i,j,flag = 1;
DataType temp;
for(i=1;i<n&&flag==1;i++){
flag = 0;//记录是否换过位置的标志位
for(j=0;j<n-i;j++){
if(a[j].key>a[j+1].key){//如果逆序,则交换位置
flag = 1;
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
有时,待排序的数据元素序列已基本有序,这样,实际上并不需要全部执行完外循环的n-1次循环过程,数据元素就已经全部排列就绪。
测试代码
#include <stdio.h>
#include <stdlib.h>
typedef int KeyType;
typedef struct{
KeyType key;
}DataType;
void BubbleSort(DataType a[], int n){//用冒泡排序对a[]进行排序
int i,j,flag = 1;
DataType temp;
for(i=1;i<n&&flag==1;i++){
flag = 0;//记录是否换过位置的标志位
for(j=0;j<n-i;j++){
if(a[j].key>a[j+1].key){//如果逆序,则交换位置
flag = 1;
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
void main(void){
int i=0;
DataType array[8]={38,5,19,26,49,97,1,66};
DataType array2[8];
printf("原数组顺序:");
for(i=0;i<8;i++){
printf("%d ",array[i]);
}
printf("\n\n");
HeapSort(array,8);
printf("冒泡排序之后结果:");
for(i=0;i<8;i++){
printf("%d ",array[i]);
}
getch(0);
}
冒泡排序的过程图
复杂度计算
冒泡排序算法的最好情况是,数据元素集合已全部排好序,这时循环n-1次,每次循环都因没有交换动作而退出,因此冒泡排序算法最好情况的时间复杂度为O(n);
冒泡排序算法的最坏情况是,数据元素集合全部逆序存放,这时循环n-1次,比较次数和交换移动次数共计为:
因此,冒泡排序算法最坏情况的时间复杂度为O(n2)。
冒泡排序算法的空间复杂度为O(1)。显然,冒泡排序算法是一种稳定的排序方法。