4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
实现代码:包含标准冒泡程序和两次的改进,并使用了函数的重载、标准库容器等等
/***************************************************************************
* @file main.cpp
* @author MISAYAONE
* @date 24 March 2017
* @remark 24 March 2017
* @theme Bubble Sort
***************************************************************************/
#include
#include
using namespace std;
//传入数组首尾指针,标准冒泡排序
void Bubble_sort(int *begin, int *end)
{
for (auto p1 = begin; p1 != end; ++p1)
{
for (auto p2 = begin; p2 != end-1; ++p2)
{
if (*p2 > *(p2+1))
{
int val_temp = *p2;
*p2 = *(p2+1);
*(p2+1) = val_temp;
}
}
}
}
//对函数进行重载,传入一对迭代器,同时进行第一次改进
//第一次改进:用于标志某一趟排序过程中是否有数据交换
//如果进行某一趟排序时并没有进行数据交换,则说明数据已经按要求排列好
//可立即结束排序,避免不必要的比较过程
void Bubble_sort(vector::iterator begin, vector::iterator end)
{
int flag= 0;
for (auto p1 = begin; p1 != end; ++p1)
{
flag = 0;
for (auto p2 = begin; p2 != end-1; ++p2)
{
if (*p2 > *(p2+1))
{
int val_temp = *p2;
*p2 = *(p2+1);
*(p2+1) = val_temp;
flag = 1;//表示此轮循环进行了交换
}
}
if (flag == 0)//上一轮循环中未进行交换,直接跳出
{
break;
}
}
}
//对函数进行重载,传入数组指针和数组大小,同时进行第二次改进
/*第二次改进:传统冒泡排序中每一趟排序操作只能找到一个最大值或最小值*/
/*我们考虑利用在每趟排序中进行正向和反向两遍冒泡的方法一次可以得到两个最终值(最大者和最小者)*/
/*从而使排序趟数几乎减少了一半*/
void Bubble_sort(int a[],int size)
{
int low = 0;
int high = size-1;
while(high > low)
{
for (int i = low; i != high; ++i)//正向冒泡,确定最大值
{
if (a[i] > a[i+1])
{
int temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
--high;
for (int j = high; j != low; --j)//反向冒泡,确定最小值
{
if (a[j] < a[j-1])
{
int temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
}
++low;
}
}
int main(int argc,char** argv)
{
int a[10] = {1,5,8,7,9,6,4,3,2,0};
int b[10] = {1,5,8,7,9,6,4,3,2,0};
vector vec(a,a+10);
Bubble_sort(begin(a),end(a));//标准库的begin()和end()函数
cout<<"内置数组冒泡排序后:";
for (int i = 0; i < 10; ++i)
{
cout<
一般我们学到的第一个排序算法就是冒泡排序,这在面试笔试中是一个很常见的考点,平均时间空间复杂度,最好最坏情况下的时间空间复杂度,在不同情况下每一趟的比较次数,以及加标志位减少比较次数等,都是需要注意的地方。
复杂度分析:
冒泡排序对 n 个元素需要 O(n^2) 的比较次数,且可以原地排序,无需辅助空间。
冒泡排序仅适用于对于含有较少元素的数列进行排序。
最差时间复杂度 O(n^2)
平均时间复杂度 O(n^2)
最优时间复杂度 O(n)
最差空间复杂度 O(n),辅助空间 O(1)
特点分析:稳定算法(stable)、in place算法
例题1:对于整数序列100,99,98,…3,2,1,如果将它完全倒过来,分别用冒泡排序,它们的比较次数和交换次数各是多少?
答:冒泡排序的比较和交换次数将最大,都是1+2+…+n-1=n(n-1)/2=50×99=4545次。
例题2:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,不能申请额外的空间
#include
#include
#include
using namespace std;
//传入首尾迭代器
void Bubble_sort1(string::iterator begin, string::iterator end)
{
for (auto p1 = begin; p1 != end; ++p1)
{
for (auto p2 = begin; p2 != end-1; ++p2)
{
if (*p2 >= 'A' && *p2 <= 'Z')//是大写字母就往后传递
{
int val_temp = *p2;
*p2 = *(p2+1);
*(p2+1) = val_temp;
}
}
}
}
int main(int argc,char** argv)
{
string test = "sadhiUASVoijiashKUASYUI";
Bubble_sort1(test.begin(),test.end());
cout<