冒泡排序算法的原理如下:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
时间复杂度:
若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数 和记录移动次数 均达到最小值:
, 。
所以,冒泡排序最好的时间复杂度为 。
若初始文件是反序的,需要进行 趟排序。每趟排序要进行 次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。
在这种情况下,比较和移动次数均达到最大值:
冒泡排序的最坏时间复杂度为 。
综上,因此冒泡排序总的平均时间复杂度为 。
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
template<class Data>
class CSortingBubbling
{
public:
CSortingBubbling();
~CSortingBubbling();
public:
void sorting(Data arr[], int length);
void BubbleSort(Data arr[], int len);
void swap(Data& a, Data& b);
};
template<class Data>
CSortingBubbling<Data>::CSortingBubbling() {
}
template<class Data>
CSortingBubbling<Data>::~CSortingBubbling()
{
}
/************************************************************************/
/* 它是一种较简单的排序算法。它会遍历若干次要排序的数列,每次遍历时,它都会从前往后依次的比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。这样,一次遍历之后,最大的元素就在数列的末尾! 采用相同的方法再次遍历时,第二大的元素就被排列在最大元素之前。重复此操作,直到整个数列都有序为止 */
/************************************************************************/
template<class Data>
void CSortingBubbling<Data>::sorting(Data arr[], int length) {
int max_index = length - 1;
for (int i = 0;i < length;i++)
{
bool is_exchange = true;
max_index = (length - i) > max_index ? max_index : (length - i);
int _max_index = max_index;
for (int j = 0;j < _max_index;j++)
{
if (arr[j] > arr[j+1])
{
is_exchange = false;
swap(arr[j], arr[j + 1]);
/************************************************************************/
/* 记录最后交换,后面没有交换说明j后面的数字已经是有序的没必要没次都全部循环 */
/************************************************************************/
max_index = j;
}
}
/************************************************************************/
/*循环结束is_exchange为true说明本次循环发现数组已经有序不需要再次进行交换*/
/************************************************************************/
if (is_exchange)
break;
}
}
/************************************************************************/
/* 换个思路,每次找到最大值放到最后再查找最小值放到数组最前面*/
/************************************************************************/
template<class Data>
void CSortingBubbling<Data>::BubbleSort(Data arr[], int len)
{
int i = 0;
int j = 0;
int n = 0;//同时找最大值的最小需要两个下标遍历
bool flag = true;
int pos = 0;//用来记录最后一次交换的位置
int k = len - 1;
for (i = 0; i < len - 1; i++)//确定排序趟数
{
pos = 0;
flag = 0;
//正向寻找最大值
for (j = n; j < k; j++)//确定比较次数
{
if (arr[j] > arr[j + 1])
{
//交换
swap(arr[j], arr[j + 1]);
flag = false;//加入标记
pos = j;//交换元素,记录最后一次交换的位置
}
}
if (flag)//如果没有交换过元素,则已经有序,直接结束
return;
k = pos;//下一次比较到记录位置即可
//反向寻找最小值
for (j = k; j > n; j--)
{
if (arr[j] < arr[j - 1]) {
swap(arr[j], arr[j - 1]);
flag = false;
}
}
n++;
if (flag)//如果没有交换过元素,则已经有序,直接结束
return;
}
}
template<class Data>
void CSortingBubbling<Data>::swap(Data& a, Data& b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}