冒泡排序——原意是说鱼从水底下吐泡泡,然后一直漂浮到水面上的过程,冒泡排序就是不断的将一个元素不断的与后面的元素进行比较,如果大于(升序)就叫交换两个元素的位置,直到比较到末尾元素为止,在将其余元素进行相同的操作,知道所有的元素都排到最终的位置,排序完成。
图示举例(单趟冒泡过程):
冒泡排序过程:
算法步骤:
(1)比较相邻元素,如果第一个比第二个大就交换;
(2)对每一个相邻的元素进行同样的工作,从开始直到最后一对,通过比较最大的数据会跑到本次的最后位置;
(3)针对所有的元素进行同样的操作;
(4)直到没有任何一对数字需要比较时排序结束。
时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:稳定
代码实现:
template<class T>
void BubbleSort(T* arr, size_t n)
{
assert(arr);
for (size_t i = 0; i < n; ++i)
{
for (size_t j = 0; j < n - i - 1; j++)
{
if (arr[j]>arr[j+1])
{
swap(arr[j], arr[j+1]);
}
}
}
}
template<class T>
void Print(T* arr, size_t n)
{
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void TestBubbleSort()
{
int arr[] = { 1, 3, 4, 5, 6, 7, 2, 9, 8 };
BubbleSort<int>(arr, sizeof(arr) / sizeof(arr[0]));
Print<int>(arr, sizeof(arr) / sizeof(arr[0]));
}
代码运行结果:
冒泡排序优化
方法:对于上面的排序方法,内排序中不管如何我们都需要将本次比较的末尾,如果我们能够判断arr[j]<arr[j+1],就可以结束本次比较,直接进入外层循环,比较下一次要比较的元素,这样就可以减让不需要的内层排序消耗,达到提升效率的目的;
代码实现:
template<class T>
void Print(T* arr, size_t n)
{
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
template<class T>
void BubbleSort(T* arr, size_t n) //优化
{
assert(arr);
int flag = 0;
for (size_t i = 0; i < n; ++i)
{
flag = 0;
for (size_t j = 0; j < n - i - 1; j++)
{
if (arr[j]>arr[j + 1])
{
swap(arr[j], arr[j + 1]);
flag = 1;
}
}
if (flag == 0)
break;
}
}
void TestBubbleSort()
{
int arr[] = { 1, 3, 4, 5, 6, 7, 2, 9, 8 };
BubbleSort<int>(arr, sizeof(arr) / sizeof(arr[0]));
Print<int>(arr, sizeof(arr) / sizeof(arr[0]));
}
运行结果: