简体   繁体   English

当我使用quicksort对双向链接列表进行排序时,用户会消失

[英]Users dissapear when I sort a doubly-linked list using quicksort

I have a doubly-linked list and I want to sort the users by their ELO. 我有一个双向链接的列表,我想按用户的ELO对其排序。

The problem is that when the function swap() is called, some users dissapear 问题在于,当调用函数swap()时,某些用户会消失

This is what I get in my console: https://imgur.com/a/pJSPSnW 这是我在控制台中得到的: https : //imgur.com/a/pJSPSnW

As you can see, the first swap (between players 1 and 2) is done correctly. 如您所见,第一次交换(玩家1和2之间)正确完成。 But, when it swaps players 3 and 4, user1 dissapears. 但是,当它交换玩家3和4时,user1消失了。

I think that the problem is inside the function swap(), but I can't figure out where exactly 我认为问题出在函数swap()内,但我无法弄清楚确切的位置

Code: User/Node declaration 代码:用户/节点声明

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

QuickSortRecursive function 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 function 快速排序功能

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

Partition function 分区功能

    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;
}

Swap function 交换功能

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

Feel free to get into my project's github https://github.com/pablogalve/ELO-System 随意进入我项目的github https://github.com/pablogalve/ELO-System

I would appreciate your help :) 谢谢您的帮助:)

In your if (areTheyNeighbors(A, B)) block, your linked list pointers end up looking like this: 在您的if (areTheyNeighbors(A, B))块中,链接列表指针最终看起来像这样: 指针 Notice that: 注意:

  • Both of B's pointers are pointed at A B的两个指针都指向A
  • Both A and A->next think B is their previous list element A和A->next认为B是他们先前的列表元素

This causes multiple problems in list traversal, and might be what causes the first element in the list to be lost. 这会导致列表遍历中出现多个问题,并且可能是导致列表中第一个元素丢失的原因。

If A and B are neighbors, this should swap them properly. 如果A和B是邻居,则应正确交换它们。

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

Amanda's answer shows one way to deal with adjacent nodes, but there doesn't need to be a special case to handle adjacent versus non-adjacent nodes, if the swapping is done first by swapping what is pointing to the two target nodes, then swapping the pointers within the two target nodes. Amanda的答案显示了一种处理相邻节点的方法,但是并不需要特殊情况来处理相邻节点与非相邻节点,如果先通过交换指向两个目标节点的内容来完成交换,然后再进行交换两个目标节点中的指针。

    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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM