Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何简化两个相互相似的函数_C++_Algorithm_Sorting_Quicksort - Fatal编程技术网

C++ 如何简化两个相互相似的函数

C++ 如何简化两个相互相似的函数,c++,algorithm,sorting,quicksort,C++,Algorithm,Sorting,Quicksort,我是一名学习计算机工程的学生。 今天我用C++学习快速排序。 这是一个非常棒的算法,我认识到快速排序需要 升序和反序的两个函数。 下面是我的代码 #include <iostream> #define ASCENDING 0 #define DESCENDING 1 #define MAX_SIZE 50001 using namespace std; int numberCnt; int sortManner; int list[MAX_SIZE]; void GetIn

我是一名学习计算机工程的学生。 今天我用C++学习快速排序。 这是一个非常棒的算法,我认识到快速排序需要 升序和反序的两个函数。 下面是我的代码

#include <iostream>
#define ASCENDING 0 
#define DESCENDING 1
#define MAX_SIZE 50001

using namespace std;


int numberCnt;
int sortManner;
int list[MAX_SIZE];

void GetInput();
void QuickSort(int* list, int left, int right, int(*partition)(int*, int, int));
int PartitionAscending(int* list, int left, int right);
int PartitionDescending(int* list, int left, int right);
void Swap(int &a, int &b);

int main(){
    GetInput();
    QuickSort(list, 0, numberCnt - 1, sortManner == ASCENDING ? PartitionAscending : PartitionDescending);
    for (int i = 0; i < numberCnt; i++){
        cout << list[i] << endl;
    }

    return 0;
}

void QuickSort(int* list, int left, int right, int (*partition)(int*,int,int)){
    if (left < right){
        int pivot = partition(list, left, right);
        QuickSort(list, left, pivot - 1, partition);
        QuickSort(list, pivot + 1, right, partition);
    }
}
int PartitionAscending(int* list, int left, int right){
    int pivotVal = list[left];
    int pivotIdx = left;
    int low = left;
    int high = right + 1;

    do{
        do{
            low++;
        } while (list[low] < pivotVal);
        do{
            high--;
        } while (list[high] > pivotVal);
        if (low < high)
            Swap(list[low], list[high]);
    } while (low < high);

    Swap(list[pivotIdx], list[high]);

    return high;
}

int PartitionDescending(int* list, int left, int right){
    int pivotVal = list[left];
    int pivotIdx = left;
    int low = left;
    int high = right + 1;

    do{
        do{
            low++;
        } while (list[low] > pivotVal);
        do{
            high--;
        } while (list[high] < pivotVal);
        if (low < high)
            Swap(list[low], list[high]);
    } while (low < high);

    Swap(list[pivotIdx], list[high]);

    return high;
}

void Swap(int &a, int &b){
    int temp = a;
    a = b;
    b = temp;
}

void GetInput(){
    cin >> numberCnt >> sortManner;
    for (int i = 0; i < numberCnt; i++)
        cin >> list[i];
}
#包括
#定义升序0
#定义降序1
#定义最大尺寸50001
使用名称空间std;
整数;
国际索特曼酒店;
整数列表[最大大小];
void GetInput();
无效快速排序(int*列表、int左、int右、int(*分区)(int*、int、int));
int分区升序(int*列表、int左、int右);
int PartitionDescending(int*列表、int左、int右);
无效掉期(内部和a、内部和b);
int main(){
GetInput();
快速排序(列表,0,numberCnt-1,sortManner==升序?分区升序:分区降序);
对于(int i=0;i>numberCnt>>sortManner;
对于(int i=0;i>列表[i];
}
你知道它们的功能非常相似! 这对我来说似乎太浪费了

如何简化功能

如果你不懂我的台球英语
请不要犹豫,让我知道:)

在函数中添加另一个参数,指定是否需要升序或降序调用,布尔
升序
可以做到这一点,并按如下方式计算循环条件:

do{
   low++;
} while ( ascending ? (list[low] < pivotVal) : (list[low] > pivotVal));
do{
低++;
}while(升序)(list[low]pivotVal));

您的分区可以使用比较函子,类似于:

template <typename Comp>
int Partition(int* list, int left, int right, Comp comp){
    int pivotVal = list[left];
    int pivotIdx = left;
    int low = left;
    int high = right + 1;

    do{
        do{
            low++;
        } while (comp(list[low], pivotVal));
        do{
            high--;
        } while (!comp(list[high], pivotVal));
        if (low < high)
            Swap(list[low], list[high]);
    } while (low < high);

    Swap(list[pivotIdx], list[high]);

    return high;
}

int PartitionAscending(int* list, int left, int right){
    return Partition(list, left, right, [](int l, int r){ return l < r; });
    // or return Partition(list, left, right, std::less<int>());
}

int PartitionDescending(int* list, int left, int right){
    return Partition(list, left, right, [](int l, int r){ return l > r; });
    // or return Partition(list, left, right, std::greater<int>());
}
模板
int分区(int*列表、int左、int右、Comp-Comp){
int pivotVal=列表[左];
int pivotIdx=左;
int低=左;
int高=右+1;
做{
做{
低++;
}而(comp(list[low],pivotVal));
做{
高--;
}而(!comp(list[high],pivotVal));
如果(低<高)
交换(列表[低]、列表[高];
}而(低<高);
交换(列表[pivotIdx],列表[high]);
高回报;
}
int分区升序(int*列表、int左、int右){
返回分区(列表,左,右,[](intl,intr){returnlr;});
//或者返回分区(列表、左、右、std::greater());
}

我会将函数简化为这个答案中给出的一个函数,但也会保持
分区升序
/
分区降序
,因为函数本身只是让它们使用正确的
comp
值调用一般的
分区
函数,这在代码中会很明显地看出您所使用的是什么打电话给我道歉,你刚才已经在回答中添加了我的观点:)