当我使用快速排序对双向链表进行排序时,用户消失了
Users dissapear when I sort a doubly-linked list using quicksort
我有一个双向链表,我想按用户的 ELO 对用户进行排序。
问题是调用函数swap()时,部分用户消失
这是我在控制台中得到的:
https://imgur.com/a/pJSPSnW
如您所见,第一次交换(玩家 1 和 2 之间)已正确完成。
但是,当它交换玩家 3 和 4 时,user1 消失了。
我认为问题出在函数 swap() 内部,但我无法弄清楚具体位置
代码:
User/Node声明
struct user {
public:
string username;
float ELO = NULL; //Score of the user
user* next = nullptr;
user* previous = nullptr;
};
QuickSort递归函数
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);
}
}
快速排序函数
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
非常感谢你的帮助:)
在您的 if (areTheyNeighbors(A, B))
块中,您的链表指针最终看起来像这样:
请注意:
- B的两个指针都指向A
- A和
A->next
都认为B是他们之前的列表元素
这会导致列表遍历出现多个问题,并且可能是导致列表中第一个元素丢失的原因。
如果 A 和 B 是邻居,这应该正确交换它们。
A->previous = B;
B->previous = swapperVector[0];
A->next = swapperVector[3];
B->next = A;
Amanda 的回答显示了一种处理相邻节点的方法,但是如果首先通过交换指向的内容来完成交换,则不需要特殊情况来处理相邻节点与 non-adjacent 节点两个目标节点,然后交换两个目标节点内的指针。
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);
我有一个双向链表,我想按用户的 ELO 对用户进行排序。
问题是调用函数swap()时,部分用户消失
这是我在控制台中得到的: https://imgur.com/a/pJSPSnW
如您所见,第一次交换(玩家 1 和 2 之间)已正确完成。 但是,当它交换玩家 3 和 4 时,user1 消失了。
我认为问题出在函数 swap() 内部,但我无法弄清楚具体位置
代码: User/Node声明
struct user {
public:
string username;
float ELO = NULL; //Score of the user
user* next = nullptr;
user* previous = nullptr;
};
QuickSort递归函数
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);
}
}
快速排序函数
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
非常感谢你的帮助:)
在您的 if (areTheyNeighbors(A, B))
块中,您的链表指针最终看起来像这样:
- B的两个指针都指向A
- A和
A->next
都认为B是他们之前的列表元素
这会导致列表遍历出现多个问题,并且可能是导致列表中第一个元素丢失的原因。
如果 A 和 B 是邻居,这应该正确交换它们。
A->previous = B;
B->previous = swapperVector[0];
A->next = swapperVector[3];
B->next = A;
Amanda 的回答显示了一种处理相邻节点的方法,但是如果首先通过交换指向的内容来完成交换,则不需要特殊情况来处理相邻节点与 non-adjacent 节点两个目标节点,然后交换两个目标节点内的指针。
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);