当我调用打印函数时,我的程序通过气泡排序运行后会显示未排序的数据。我将自己的代码与朋友进行了比较,并在geeksforgeeks(https://www.geeksforgeeks.org/bubble-sort/)上找到了有关冒泡排序的文章,无论出于何种原因我的数据都无法排序。
我正在为我的大学数据结构课程编写一个具有4种排序功能的程序。理论上应该发生的是程序读取具有8000个随机数的数据文件,并根据调用的排序类型(气泡排序,插入排序,选择排序和快速排序)对数据进行排序。调用打印函数,它将每第1000个数据元素显示一次,以表明该数据确实已排序。我试过在main中对我的打印进行编码,将打印调用放入排序功能中,然后使用一个函数进行打印,Quadruple检查了我的排序功能。我还尝试了不同的编译器和不同的计算机,但我怀疑它的代码有些时髦。
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;
const int arraysize = 8000;
int numcompares, numcopies;
void swapem(double a, double b)
{
double temp;
temp = a;
a = b;
b = temp;
}
void bubblesort(double r[], int n)
{
int j, i;
for (j = 0; j < n - 1; j++)
{
for (i = 0; i < n - 1; i++)
{
numcompares++;
if (r[i] > r[i + 1])
{
swapem(r[i], r[i + 1]);
numcopies += 3;
}
}
}
}
void printem(double r[])
{
cout << r[1000] << ", " << r[2000] << ", " << r[3000] << ", " <<
r[4000] << ", " << r[5000] << ", " << r[6000] << ", " << r[7000] << ", " << r[7999] << endl;
}
int main()
{
ifstream inf("data.dat");
ofstream outf("sorted.ot");
string sortname;
double arraynums[arraysize];
for (int i = 0; i < arraysize; i++)
{
inf >> arraynums[i];
}
bubblesort(arraynums, arraysize);
system("pause");
return 0;
}
void printem(double r[], int n)
{
int i;
for (i = 0; i < n; i++)
cout << r[i]<< ", ";
}
printem(arraynums,20); // in main
for (int i = 0; i < 10; i++)
{
cout << arraynums[i] << endl;
}
41275.4
12113.1
50676
7662.34
50688.3
-7926.28
13672.8
-3212.9
-13046.5
-16798
输出应为: -16798 -13046.5 -7926.28 -3212.9 7662.34 12113.1 13672.8 41275.4 50676 50688.3
但是它保持未排序形式: 41275.4 12113.1 50676 7662.34 50688.3 -7926.28 13672.8 -3212.9 -13046.5 -16798
答案 0 :(得分:1)
欢迎堆栈溢出!看来您这里是按值传递与按引用传递的经典案例。 C语言中的函数无法在其自身范围之外修改其参数的值,但它可以访问由其参数引用的内存并对其进行修改。
swapem()仅在方法本身的范围内对a和b进行更改,而不会更新在a和b位置处引用的数据。要解决此问题,可以将a和b作为指针传递,并修改指针引用的值,如下所示:
void swapem(double *a, double *b) {
double temp = *a;
*a = *b;
*b = temp;
}
并且方法本身将使用这些数组元素的引用而不是它们的值。对于上面的示例,它看起来像这样:
swapem(r + i, r + (i + 1))
在按值传递和按引用传递时,有很好的一组相关信息here。有一定的技术性,因为您实际上是将指针的值传递到上述示例中,从技术上讲,它使它按值传递,但这是对您要修改的实际变量的引用,因此概念仍然存在在这里成立。
答案 1 :(得分:0)
了解您的bubbleort()函数的作用很重要。它收到数组成员'arraynums'的 COPY 。它对其进行排序,然后终止。在此函数结束时,您没有带此排序的数组。
但是,等等,即使您的swapem()也不起作用,因为它也将接收2个值的副本并在本地进行交换。调用后,您将不再需要交换值。
要解决此问题,您需要在swapem()函数中使用传递引用。
void swapem(double & a, double & b)
{
double temp;
temp = a;
a = b;
b = temp;
}
在bubbelsort()函数中,如果您想让bubbleort进行打印,则可以立即使用printem()函数。取而代之的是,您可以简单地将数组作为对bubbleort()的引用进行传递,并在其末尾获得修改后的arraynums数组。