目录
冒泡排序:(无序区,有序区)。从无序区通过交换找出最大元素放到有序区前端。
一、思路
1、比较相邻元素,如果第一个比第二个大,交换他们。
2、对每一对相邻元素做同样操作,从开始第一对倒最后一对。这步做完后,最后的元素是最大的。
3、针对所有元素重复以上步骤,除了最后一个。
4、持续每次对越来越少的元素重复以上步骤,直到没有一对数字需要比较。
二、普通写法
void BubbleSort(vector<int> &v)
{
int len = v.size();
for (int i = 0; i < len - 1; i++) // 确定排序趟数
{
for (int j = 0; j < len - 1 - i; j++) // 确定比较次数
{
if (v[j] > v[j + 1])
{
swap(v[j], v[j + 1]);
}
}
}
}
三、模板写法
template<typename T>
void BubbleSort(T arr[], int len)
{
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
swap(arr[j], arr[j + 1])
}
}
}
}
四、优化一
假设我们现在排序arr[]={1, 2, 3, 4, 5, 6, 7, 8, 10, 9}这组数据,按照上面排序方式,第一趟排序后将10和9交换已经有序,接下来的8趟排序就是多余的,什么也没有做。所以我们可以在交换的地方做一个标记,如果那一趟排序没有交换元素,说明这组数据已经有序,不用再继续下去。
void BubbleSort(vector<int> &v)
{
int len = v.size();
for (int i = 0; i < len - 1; i++) // 排序趟数
{
int flag = 0;
for (int j = 0; j < len - 1 - i; j++)
{
if (v[j] > v[j + 1])
{
swap(v[j], v[j + 1]);
flag = 1;
}
}
if (flag == 0) // 如果没有交换过元素,则已经有序
{
return;
}
}
}
五、优化二
优化一仅适用于连片有序而且整体无序的数据(如:1, 2, 3, 4,7, 6, 5)。但是对于前面大部分是无序而后边小半部分有序的数据(1, 2, 5, 7, 4, 3, 6, 8, 9, 10)排序效率也不客观。对于这种类型数据,我们可以继续优化。我们可以记下最后一次交换的位置,后边没有交换,必然是有序的,然后下一次排序从第一个比较到上次记录的位置结束即可。
void BubbleSort(vector<int> &v)
{
int len = v.size();
int lastChangePos = 0;
int flag = 0;
int k = len - 1;
for (int i = 0; i < len - 1; i++)
{
lastChangePos = 0;
flag = 0;
for (j = 0; j < k; j++)
{
if (v[j] > v[j + 1])
{
swap(v[j], v[j + 1]);
flag = 1;
lastChangePos = 1;
}
}
if (flag == 0)
{
return;
}
k = lastChangePos;
}
}
六、优化三
优化二的效率有很大提升,还有一种优化方法可以继续提高效率。大致思想就是一次排序可以确定两个值,正向扫描找到最大值交换到最后,反向扫描找到最小值交换到最前面。例如:排序数据1, 2, 3, 4, 5, 6, 0.
void BubbleSort(vector<int> &v)
{
int len = v.size();
int flag = 0;
int lastChangePos = 0;
int k = len - 1;
int n = 0; // 同时找到最大值和最小值需要两个下标遍历
for (int i = 0; i < len - 1; i++) // 确定排序趟数
{
lastChangePos = 0;
flag = 0;
// 正向查找最大值
for (int j = n; j < k; j++) // 确定比较次数
{
if (v[j] > v[j + 1])
{
swap(v[j], v[j + 1]);
flag = 1;
lastChangePos = j;
}
}
if (flag == 0) return;
k = lastChangePos; // 下一次比较到记录位置即可
// 反向查找最小值
for (j = k; j > n; j--)
{
swap(v[j], v[j - 1]);
flag = 1;
}
n++;
if (flag == 0) return;
}
}