【问题标题】:C++ Sorting Array struct by using QuickSortC++ 使用 QuickSort 对数组结构进行排序
【发布时间】:2019-11-28 11:18:03
【问题描述】:

我必须使用 QuickSort 算法(不是内置函数,我必须手动编写)对结构数组进行排序,还要测量工作时间并与标准 C++ 排序函数进行比较。在我编译我的代码后,输出文件(sort.txt)看起来是一样的。我做错了什么?

struct Info
{
    int Birth;
    char Name[20];
    char SurName[25];
};

template <keys T>
struct Comparer {

    bool operator ()(const Info &m1, const Info &m2) const {

        return (T == YEAR ? m1.Birth > m2.Birth : strcmp(m1.Name, m2.Name) > 0);
    }

};

int partition(vector<Info> &vArray, int start, int end) {
    int pivotValue, pivotIndex, mid;

    mid = (start + end) / 2;
    swap(vArray[start].Birth, vArray[mid].Birth);
    swap(vArray[start].Name, vArray[mid].Name);
    swap(vArray[start].SurName, vArray[mid].SurName);


    pivotIndex = start;
    pivotValue = vArray[start].Birth;

    for (int scan = start + 1; scan <= end; scan++) {
        if (vArray[scan].Birth < pivotValue) {
            pivotIndex++;
            swap(vArray[pivotIndex].Birth, vArray[scan].Birth);
            swap(vArray[pivotIndex].Name, vArray[scan].Name);
            swap(vArray[pivotIndex].SurName, vArray[scan].SurName);

        }
    }

    swap(vArray[start].Birth, vArray[pivotIndex].Birth);
    swap(vArray[start].Name, vArray[pivotIndex].Name);
    swap(vArray[start].SurName, vArray[pivotIndex].SurName);
    return pivotIndex;
}

template <keys T>
void quickSort(vector<Info>&vArray, int start, int end) {
    int pivotPoint;
    if (start < end) {

        pivotPoint = partition(vArray, start, end);

        quickSort<T>(vArray, start, pivotPoint - 1);

        quickSort<T>(vArray, pivotPoint + 1, end);
    }
}

void Print(const vector<Info> Mas)
{
    string path = "sort.txt";
    ofstream Out;
    Out.open(path);
    if (!Out.is_open()) {
        cout << "wdw" << endl;

    }
    else  {
        for (int i = 0; i < (int)Mas.size(); i++)
            Out << Mas[i].Name << " " << Mas[i].SurName << " " << Mas[i].Birth << "\n";
    }
    Out.close();
}

template<keys T>
bool isSorted(vector<Info> Mas)
{
    Comparer<T> c;
    for (int i = 0; i < Mas.size() - 1; i++)
        if (c(Mas[i], Mas[i + 1]))
            return false;
    return true;
}

在主函数中:

        quickSort<YEAR>(Mas, 0, pow(rows, i));

    Print(Mas);

我的完整代码:https://www.codepile.net/pile/e2z3l7E0

Names.txt 和 Surnames.txt 生成:https://dropmefiles.com/riOmD

【问题讨论】:

  • 除了我在回答中指出的明显错误之外。当您提出问题时,习惯于发送minimal reproducible example。例如,template &lt;keys T&gt; 中的 keys 是什么?
  • keys 是什么类型?不要让我们质疑。在问题中添加足够的代码,以便其他人能够编译它。
  • 这不是它的工作方式。人们很少愿意通读大量工作代码来找到失败的部分。尤其是当您使用非标准的东西时,例如conio.h 等。没有多少人可以编译该代码。您应该在这里发布人们帮助您所需的最小代码。从您的完整代码中创建一个minimal reproducible example。检查它是否也失败 - 并将 that 代码放入问题中。如果您不确定是否包含非标准部件,请使用good online compiler 并在更新您的问题之前尝试在那里编译它。
  • 那是因为你有不止一个错误。你明白了,这样称呼它:quickSort&lt;YEAR&gt;(Mas, 100000, 0); 会有 no 排序吗? start&gt; 而不是 end,所以 if 语句中的条件将是 false。正确的?你有多少元素我vector&lt;Info&gt; Mas?做一个minimal reproducible example,这样我们就可以编译和你一样的代码,这可能会很快解决。
  • 这不是minimal reproducible example,除非您怀疑失败的代码与非标准的&lt;conio.h&gt; 函数等有关。&lt;chrono&gt; 部分进行计时不是最小的例子。使用标准编译器编译它,godbolt.org/z/KdncC- 然后edit 问题并将该代码放在那里。

标签: c++ vector struct quicksort


【解决方案1】:

这些部分保证不会进行排序:

if (start < end) { 
//... do the sorting
} // else don't
//                   start  end                      
quickSort<YEAR>(Mas, 100000, 0);

在您的 partition() 函数中,您可以添加一些调试打印以使您走上正轨:

    int pivotValue, pivotIndex, mid;

    mid = (start + end) / 2;
    std::cout << "size: " << vArray.size() << " start: " << start << " mid: " << mid
              << " end: " << end << "\n";
    // ...

    for (int scan = start + 1; scan <= end; scan++) {
        std::cout << "scan: " << scan << "\n";
        // ...

您会注意到,实际上您的索引超出了范围:

size: 1 start: 0 mid: 0 end: 1
scan: 1

vArray.size()1vArray[1] 是非法的,因此程序具有未定义的行为。

您的Info 有一个char Name[10] 成员,这意味着其中最多只能存储9 个字符的名称。您的 names.txt 文件包含 59 个更长的名称。因此,您将越界写入,可能写入以下SurName 成员。

【讨论】:

    最近更新 更多