2015-05-11 7 views
1

Я студент, изучающий компьютерную инженерию. Сегодня я учился быстро сортировать, используя 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

Добавить другой аргумент в вашу функцию, что бы указать, если вам нужен возрастающий или убывающий звонке булево ascending может сделать это, и вычислить условие цикла, как это:

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

Ваш раздел может взять функтор сравнения, что-то вроде:

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>()); 
} 
+0

Я бы упростил функции в один, как указано в этом ответе, но также сохранил 'PartitionAscending' /' PartitionDescending', поскольку сами функции просто заставляют их вызывать общую функцию 'Partition' с правильным значением' comp' - делает это сразу очевидным в код, по которому вы звоните – Kvothe

+0

Прошу прощения, вы только что добавили мою точку в свой ответ уже :) – Kvothe

Смежные вопросы