交换排序是通过两两比较待排序区相邻的两个元素,若两个元素次序相反,则交换位置。直到没有反序的元素为止。
一、排序思路
冒泡排序通过无序区中相邻的两个元素间关键字的比较和位置的交换,使无序区中关键字最小元素像气泡一样往上冒。整个算法从最下面的元素开始(j=n-1;),直到无序区最小的元素到达最上端(j>i)。
冒泡排序优化,当第i趟时已经排好序了,但算法还会进行后面的几趟比较。在一趟比较中,如果没有出现任何元素的交换,说明已经排好序了,可结束了。
二、排序算法
/***********************************************************************
* FUNCTION: 冒泡排序算法
* AUTHOR: zhuzi
* DATE: 2018-05-04
* VERSION: v1.0
* NOTES:
* MODIFICATION:
**********************************************************************/
#include <iostream>
using namespace std;
typedef int KeyType;
typedef int InfoType;
typedef struct
{
KeyType key;
InfoType data;
}RecType;
/*********************************************************************
* function: 冒泡排序
* parameters: RecType R[], 待排序数组
int n, 数组个数
* return value: 无
**********************************************************************/
void BubbleSort(RecType R[], int n)
{
int i, j;
RecType tmp;
for (i = 0; i < n - 1; i++)//遍历整个表
{
for(j = n-1; j > i; j--)//从无序区中将最小的元素交换到无序区最上端。
{
tmp = R[j];
if(R[j].key < R[j-1].key)//判断出最小值
{
tmp = R[j];
R[j] = R[j-1];
R[j-1] = tmp;
}
}
}
}
/*********************************************************************
* function: 冒泡排序,
算法优化,当第i趟已经排好序时,还会执行后面的几趟比较。
一旦算法中某一趟比较没有出现任何元素交换,就说明已经排好了
* parameters: RecType R[], 待排序数组
int n, 数组个数
* return value: 无
**********************************************************************/
void BubbleSort1(RecType R[], int n)
{
int i, j;
RecType tmp;
bool exchange;
for (i = 0; i < n - 1; i++)//遍历整个表
{
exchange = false;
for(j = n-1; j > i; j--)//从无序区中将最小的值排序到有序区中
{
tmp = R[j];
if(R[j].key < R[j-1].key)//判断出最小值
{
tmp = R[j];
R[j] = R[j-1];
R[j-1] = tmp;
exchange = true;//执行到此处,还在进行元素交换,说明还未排好序
}
}
if(!exchange)//当exchange为false时,说明已经不进行元素交换了。
return;
}
}
/*********************************************************************
* function: 输出元素
* parameters: RecType R[], 有序区数组
int n, 数组元素个数
* return value: 无
**********************************************************************/
void print(RecType R[], int n)
{
for(int i = 0; i < n ; i++)
{
cout << "R[" << i << "] <" << R[i].key << "," << R[i].data << ">" << endl;
}
}
int main(int argc, char* argv[])
{
RecType RT[] = {{1,11},{3,33},{2,22},{5,55},{5,555},{7,77},{8,88}};
BubbleSort(RT, sizeof(RT)/sizeof(RT[0]));
print(RT, sizeof(RT)/sizeof(RT[0]) );
//优化算法
BubbleSort1(RT, sizeof(RT)/sizeof(RT[0]));
print(RT, sizeof(RT)/sizeof(RT[0]) );
return 0;
}
三、算法分析
若初始数据序列是正序的,则一趟比较就可以完成。所需的比较和交换次数最小:C=n-1,M=0。冒泡排序的最好时间复杂度为O(n)。
若初始数据序列是逆序的,则需要进行n-1趟排序,每趟都要进行n-i-1趟比较,每次都必须移动元素3次(tmp = R[j]; R[j] = R[j-1];R[j-1] = tmp;)。比较和移动次数都是最大值,C=n(n-1)/2=O(n^2),M=3n(n-1)/2=O(n^2)。最坏时间复杂度为O(n^2)。
平均复杂度为O(n^2)。