iamakulov icon

Course Task Sorting Example

iamakulov | PRO | 04/11/14 09:05:14 AM UTC | 0 ⭐ | 429 👁️ | Never ⏰ | []
C |

5.22 KB

|

None

|

0 👍

/

0 👎

/**
 * @brief Структура Stack реализует динамический список-стек.
 *
 * Для того, чтобы в стеке можно было хранить любые данные, в качестве типа переменной #inf используется void*.
 */
struct Stack
{
    struct Stack *next; ///< Указатель на следующий элемент
    void *inf;  ///< Информация, хранящаясяя в данном элементе
};
 
/**
 * @brief Тип FlightInformation предназначен для хранения информации о полёте.
 */
struct FlightInformation
{
    int id; ///< Номер рейса
    size_t cityId; ///< Номер целевого города в кодификаторе
    int distance;   ///< Расстояние от Донецка до целевого города
    int adultTicketCost;    ///< Стоимость взрослого билета
    int childTicketCost;    ///< Стоимость детского билета
    char departureTime[6];  ///< Время отправления
    char arrivalTime[6];    ///< Время прибытия
};
 
/**
 * @brief Находит длину стека за O(N).
 * @param beg Указатель на начало стека.
 * @return Длина стека.
 */
size_t StackLength(const struct Stack *beg)
{
    size_t size = 0;
    struct Stack *run = beg;
    while (run != NULL) {
        ++size;
        run = run->next;
    }
    return size;
}
 
enum FieldType { FieldType_Id = 1, FieldType_CityId, FieldType_Distance,
                 FieldType_AdultTicketCost, FieldType_ChildTicketCost,
                 FieldType_DepartureTime, FieldType_ArrivalTime };
 
 
/**
 * @brief Сравнивает заданное поле структур #left и #right.
 * @param fieldType Тип поля, которое нужно сравнить.
 * @return True, если заданное поле #left <= заданного поля #right, иначе False.
 */
Bool lessOrEqualThan(const struct FlightInformation *left, const struct FlightInformation *right, enum FieldType fieldType)
{
    int compResult = 0;
 
    switch (fieldType) {
    case FieldType_Id:
        return left->id <= right->id;
    case FieldType_CityId:
        return left->cityId <= right->cityId;
    case FieldType_Distance:
        return left->distance <= right->distance;
    case FieldType_AdultTicketCost:
        return left->adultTicketCost <= right->adultTicketCost;
    case FieldType_ChildTicketCost:
        return left->childTicketCost <= right->childTicketCost;
    case FieldType_DepartureTime:
        compResult = strcmp(left->departureTime, right->departureTime);
        return compResult <= 0;
    case FieldType_ArrivalTime:
        compResult = strcmp(left->arrivalTime, right->arrivalTime);
        return compResult <= 0;
    }
 
    return False;
}
 
/**
 * @brief Сортирует стек рейсов "школьной" сортировкой по заданному полю.
 * @param archiveStack Сортируемый стек.
 * @param fieldType Тип поля, по которому нужно сортировать.
 */
void sortArchiveBySchoolSort(struct Stack *archiveStack, enum FieldType fieldType)
{
    struct Stack *left, *right;
 
    // Стек уже отсортирован, если в нём 1 или 0 элементов
    if (StackLength(archiveStack) < 2)
        return;
 
    left = archiveStack;
    right = archiveStack->next;
 
    for (left = archiveStack; left->next != NULL; left = left->next) {
        for (right = left->next; right != NULL; right = right->next) {
            if (lessOrEqualThan((struct FlightInformation *)right->inf,
                                (struct FlightInformation *)left->inf,
                                fieldType)) {
                void *inf = left->inf;
                left->inf = right->inf;
                right->inf = inf;
            }
        }
    }
}
 
/**
 * @brief Сортирует стек рейсов сортировкой вставкой по заданному полю.
 * @param archiveStack Сортируемый стек.
 * @param fieldType Тип поля, по которому нужно сортировать.
 */
void sortArchiveBySelectionSort(struct Stack *archiveStack, enum FieldType fieldType)
{
    struct Stack *left, *right;
 
    // Стек уже отсортирован, если в нём 1 или 0 элементов
    if (StackLength(archiveStack) < 2)
        return;
 
    left = archiveStack;
    right = archiveStack->next;
 
    for (left = archiveStack; left->next != NULL; left = left->next) {
        struct Stack *min = left;
        for (right = left->next; right != NULL; right = right->next) {
            if (lessOrEqualThan((struct FlightInformation *)right->inf,
                                (struct FlightInformation *)min->inf,
                                fieldType)) {
                min = right;
            }
        }
 
        if (min != left) {
            void *inf = left->inf;
            left->inf = min->inf;
            min->inf = inf;
        }
    }
}

Comments