我做了一个简单的冒泡程序,代码可以工作,但我不知道它是否正确。
我对气泡排序算法的理解是它检查一个元素和它旁边的另一个元素。
#include <iostream>
#include <array>
using namespace std;
int main()
{
int a, b, c, d, e, smaller = 0,bigger = 0;
cin >> a >> b >> c >> d >> e;
int test1[5] = { a,b,c,d,e };
for (int test2 = 0; test2 != 5; ++test2)
{
for (int cntr1 = 0, cntr2 = 1; cntr2 != 5; ++cntr1,++cntr2)
{
if (test1[cntr1] > test1[cntr2]) /*if first is bigger than second*/{
bigger = test1[cntr1];
smaller = test1[cntr2];
test1[cntr1] = smaller;
test1[cntr2] = bigger;
}
}
}
for (auto test69 : test1)
{
cout << test69 << endl;
}
system("pause");
}
答案 0 :(得分:4)
这是一个bubbleort实现。这只是一个非常基本的问题。
两项改进:
一些意见:
std::swap()
交换变量会导致更简单的代码。Here是一个更通用的例子,使用(随机访问)迭代器和我建议的改进和注释,以及here和Yves Daoust提出的改进(迭代到最后交换)和debug-prints < / p>
答案 1 :(得分:2)
算法的正确性可以解释如下。
在第一遍(内部循环)中,具有可能交换的比较T[i] > T[i+1]
可确保最大的T[i]
,T[i+1]
位于右侧。从左到右重复所有对确保最后T[N-1]
保持最大元素。 (数组仅由交换修改的事实确保没有元素丢失或重复。)
在第二轮中,通过相同的推理,N-1
第一个元素中最大的元素会转到T[N-2]
,因为T[N-1]
更大,所以它会保留在那里。
更一般地说,在K
次传递中,N-K+1
第一个元素中最大的一个元素移到T[N-K]
,停留在那里,并且下一个元素保持不变(因为它们已经是增加)。
因此,在N
通过后,所有元素都已到位。
这提示了一个简单的优化:传递中最后一次交换后的所有元素都已到位(否则交换不会是最后一个)。因此,您可以记录最后一次交换的位置,并仅执行下一次传递到该位置。
虽然这种变化似乎没有太大改善,但它可以减少通过次数。实际上,通过这个程序,通过次数等于最大位移,即元素必须走到正确位置所需的步数(右边的元素太多,一次只移动一个位置)。
在某些配置中,此数字可能很小。例如,对已经排序的数组进行排序需要一次传递,并且使用成对交换的所有元素对数组进行排序需要两次。这是从O(N²)到O(N)的改进!
答案 2 :(得分:0)
是。您的代码就像Bubble Sort一样工作。
输入:3 5 1 8 2
每次迭代后的输出:
3 1 5 2 8
1 3 2 5 8
1 2 3 5 8
1 2 3 5 8
1 2 3 5 8
1 2 3 5 8
实际上,在内循环中,我们不需要从第二次迭代开始直到数组的末尾,因为前一次迭代中最重的元素已经在最后。但这并没有太大的时间复杂性。所以,你很高兴......
小型非正式证明:
排序算法背后的想法是你通过值数组(从左到右)。我们称之为通行证。在传递期间,检查值对并交换为正确的顺序(右上角)。
在第一次通过期间,将达到最大值。到达时,max将高于它旁边的值,因此它们将被交换。这意味着max将成为传递中下一对的一部分。这将重复,直到传递完成并且max移动到阵列的右端。
在第二次传递期间,对于阵列中的第二个最高值也是如此。唯一的区别是它不会与最后的最大值交换。现在正确设置了两个最正确的值。
在每个下一个传递中,一个值将被排序到右边。
有N个值和N个通道。这意味着在N次传递后,所有N个值将按如下方式排序:
{第k大,第(k-1)个最大,......第二大,最大}
答案 3 :(得分:-1)
不,不是。更糟糕的是。变量cntr1
中没有任何意义。你应该在这里使用test1
,你应该指的是bubblesort的许多规范实现之一,而不是试图为自己做好准备。