Пользователи исчезают, когда я сортирую двусвязный список с помощью быстрой сортировки - PullRequest
0 голосов
/ 28 мая 2019

У меня есть двусвязный список, и я хочу отсортировать пользователей по их ELO.

Проблема в том, что когда вызывается функция swap (), некоторые пользователи исчезают

Этовот что я получаю в своей консоли: https://imgur.com/a/pJSPSnW

Как видите, первый обмен (между игроками 1 и 2) выполнен правильно.Но когда он меняет местами игроков 3 и 4, user1 исчезает.

Я думаю, что проблема в функции swap (), но я не могу понять, где именно

Код: Пользователь/ Объявление узла

struct user {
public:
    string username;
    float ELO = NULL; //Score of the user       
    user* next = nullptr;
    user* previous = nullptr;
};

Функция QuickSortRecursive

 void ELOManager::_quickSortRecursive(user* low, user* high) {
    if (high != nullptr && low != high && low != nullptr) {
        user* p = partition(low, high);
        _quickSortRecursive(low, p->previous);
        _quickSortRecursive(p->next, high);
    }
}

Функция QuickSort

void ELOManager::quickSort(){
    _quickSortRecursive(first, last);
}

Функция разбиения

    user* ELOManager::partition(user* low, user* high) {
    float pivot = high->ELO;

    user* i = low->previous;

    for (user* j = low; j != high && j!=nullptr; j = j->next) {
        if (j->ELO <= pivot){
            i = (i == NULL) ? low : i->next;

            swap(i, j);
        }
    }
    //i = (i == NULL) ? low : i->next;
    swap(i->next, high);
    cout << endl << "Loop finished -----------------------" << endl;
    printUsers();
    return i;
}

Функция обмена

    void ELOManager::swap(user* A, user* B) {
    user* tmp = new user();
    user* swapperVector[4];

    cout << endl << "swap1[" << A->username << "]" << endl;
    cout << "swap2[" << B->username << "]" << endl;

    if (A == B) {
        cout << "Same Users: Continue" << endl;
        return;
    }   

    swapperVector[0] = A->previous;
    swapperVector[1] = B->previous;
    swapperVector[2] = A->next;
    swapperVector[3] = B->next; 

    if (areTheyNeighbours(A, B)) {
        A->previous->next = B;
        A->next->previous = B;
        B->previous->next = A;
        B->next->previous = A;


        A->previous = B;
        B->previous = swapperVector[1];
        A->next = swapperVector[3];
        B->next = A;    
        cout << endl << "Option 1" << endl;
    }
    else {
        A->previous = swapperVector[1];
        B->previous = swapperVector[0];
        A->next = swapperVector[3];
        B->next = swapperVector[2];

        A->previous->next = B;
        A->next->previous = B;
        B->previous->next = A;
        B->next->previous = A;
        cout << endl << "Option 2" << endl;
    }

    cout <<"Print list after swap" << endl << "-----" << endl;
    printUsers();
}

Не стесняйтесь войти в github моего проекта https://github.com/pablogalve/ELO-System

Буду признателен за вашу помощь:)

Ответы [ 2 ]

1 голос
/ 28 мая 2019

Ответ Аманды показывает один из способов справиться со смежными узлами, но особого случая для обработки смежных и несмежных узлов не требуется, если замена выполняется сначала путем замены того, что указывает на два целевых узла. затем поменяйте местами указатели внутри двух целевых узлов.

    AP = A->previous;
    BP = B->previous;
    AN = A->next;
    BN = B->next;
    std::swap(AN->previous, BN->previous);
    std::swap(AP->next, BP->next);
    std::swap(A->previous, B->previous);
    std::swap(A->next, B->next);
1 голос
/ 28 мая 2019

В вашем блоке if (areTheyNeighbors(A, B)) указатели на связанный список в конечном итоге будут выглядеть так: pointers Обратите внимание:

  • Оба указателя B направлены на A
  • И A, и A->next считают B своим предыдущим элементом списка

Это вызывает многочисленные проблемы при обходе списка и может быть причиной того, что первый элемент в списке теряется.

Если A и B являются соседями, это должно правильно поменять их местами.

A->previous = B;
B->previous = swapperVector[0];
A->next = swapperVector[3];
B->next = A;
...