【问题标题】:Unable to use swap without temparary variable没有临时变量无法使用交换
【发布时间】:2021-01-18 16:06:00
【问题描述】:

快速排序程序

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
using namespace std;

// constant
enum {MAX = 10};

// class
class A
{
private:
    int arr[MAX];
public:
    A() // constructor
    {
        srand(time(0));
        for(int i = 0; i < MAX; i++)
            arr[i] = rand() % 100;
    }
    // accessing array
    int get(int i)
    {
       return arr[i];
    }
    // quick sort
    int Partition(int left, int right);
    void quickSort(int left, int right);
    void Swap(int&, int&);
};

// member function definition
int A::Partition(int left, int right)
{
    int pivot = arr[right], i = left - 1;
    for(int j = left; j <= right-1; j++)
    {
        if(arr[j] < pivot)
        {
            i++;
            Swap(arr[i], arr[j]);
        }
    }
    Swap(arr[i+1], arr[right]);
    return i+1;
}

void A::quickSort(int left, int right)
{
    if(left < right)
    {
        int pi = Partition(left, right);
        quickSort(left, pi-1);
        quickSort(pi+1, right);
    }
}

void A::Swap(int& a, int& b)
{
    a = a+b;
    b = a-b;
    a = a-b;
}

// driver
int main(void)
{
    A obj1;

    //-------Array initialized--------
    cout << "Before sorting:" << endl;
    for(int i = 0; i < MAX; i++)
        cout << setw(4) << obj1.get(i);

    //--------Sorting Array-----------
    obj1.quickSort(0, MAX-1);

    //--------Sorted Array------------
    cout << "\nAfter sorting:" << endl;
    for(int i = 0; i < MAX; i++)
        cout << setw(4) << obj1.get(i);

    return 0;
}

问题出在 swap() 函数内部。当我使用 int temp 变量交换值时,值被交换并且数组按升序排序。

但是当我在不使用临时 int 变量的情况下交换值时,我在排序数组中得到 0。如下图:

输出

Before sorting:
   89   43   18   98   23   88   52   18   1   25
After sorting:
   1   18   0   0   25   43   0   88   89   98

【问题讨论】:

  • 我怀疑问题不在于交换,而在于代码中其他地方的未定义行为。它只是基于一种或另一种实现来表现自己。
  • 自从喇叭牛仔裤第一次过时以来,用算术交换并不是一种有效的方法。
  • 所有这些+ 1- 1 调整使您不太可能在某处没有一个错误。传统的半开区间是传统的,有充分的理由,其中之一是划分区间变得更好。 (另外:除非你重用种子,否则使用随机数进行测试是个坏主意。测试用例应该是小而系统的,而不是大而随意的。)
  • 只需使用std::swap

标签: c++ quicksort


【解决方案1】:

这个错误不是因为swap,它是由调用函数发送了一个相同的变量来swap引起的。这会导致算法为 a-b 提供零。

在以下代码中:

int A::Partition(int left, int right)
{
    int pivot = arr[right], i = left - 1;
    for(int j = left; j <= right-1; j++)
    {
        if(arr[j] < pivot)
        {
            i++;
            Swap(arr[i], arr[j]); // i = j in the first run
    }
}
   Swap(arr[i+1], arr[right]); // here also exists case that i+1 = right
   return i+1;
}

对于测试:使用 if 条件过滤碰撞索引,它可以工作:

 if (i != j)Swap(arr[i], arr[j]);

 if ((i+1) != right) Swap(arr[i+1], arr[right]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多