如何在登机队列排序场景中正确使用双指针?
解决登机队列冒泡排序的编译错误与逻辑问题
看起来你在实现基于链表的登机队列冒泡排序时,在双指针操作和循环逻辑上踩了几个坑,我来帮你逐一梳理和修正:
核心错误分析
1. 双指针操作完全不符合指针类型规则
你尝试更新双指针的写法比如**r = &(r->next)、**a = &(a->next)都是错误的:
r是Passenger**类型,要访问它指向的节点的next,需要先解引用得到Passenger*:(*r)->next- 要让双指针
r移动到下一个节点的地址,应该写成r = &(*r)->next,而不是修改**r(这是修改节点内容,不是指针指向) a是Passenger*类型,**a是非法操作(解引用两次会得到Passenger结构体本身,再解引用会触发类型错误),你混淆了单指针和双指针的用法。
2. 循环条件逻辑颠倒
外层for循环的条件 i <=0 完全错误:如果队列长度size>1,初始i=size-1是正数,这个条件永远不成立,导致排序逻辑根本不会执行。应该改成 i > 0。
3. 变量初始化错误
Passenger **q = &(qPtr->next); 是错误的,因为BoardingQueue结构体里没有next成员,只有head和tail。这里你应该是想跟踪需要交换的相邻节点的前导指针,所以这个变量的初始化和用法都需要调整。
4. 内层循环未重置指针
冒泡排序每一轮都需要从头开始比较相邻元素,但你的代码里t和a在第一轮后就走到链表末尾,后续循环无法重新开始。
修正后的代码实现
我基于你的需求,用双指针实现链表的冒泡排序(交换节点指向,效率更高),同时修正所有编译错误:
#include <string.h> // 用于节点内容拷贝(可选) // 结构体声明(保持你的定义) typedef struct passenger { char name[30]; double passportNumber; int seatNumber; struct passenger* next; } Passenger; typedef struct boardingQueue { Passenger* head; Passenger* tail; } BoardingQueue; // 假设你已实现的队列长度计算函数 int calculateSize(BoardingQueue *qPtr) { int count = 0; Passenger* curr = qPtr->head; while (curr != NULL) { count++; curr = curr->next; } return count; } int sortBoardingQueue(BoardingQueue *qPtr){ // 边界条件:空队列或单节点无需排序 if (qPtr == NULL || qPtr->head == NULL || qPtr->head->next == NULL) { return 0; } int size = calculateSize(qPtr); int swapped; Passenger **prev; // 双指针,跟踪当前节点的前导指针地址 Passenger *curr; Passenger *nextNode; for (int i = size-1; i > 0; i--) { swapped = 0; prev = &qPtr->head; // 每轮从头开始遍历 curr = qPtr->head; nextNode = curr->next; for (int j = 0; j < i; j++) { // 比较座位号,需要交换节点 if (curr->seatNumber > nextNode->seatNumber) { // 交换两个节点的指向 *prev = nextNode; curr->next = nextNode->next; nextNode->next = curr; // 更新指针继续遍历 prev = &nextNode->next; nextNode = curr->next; swapped = 1; } else { // 无需交换,直接移动指针 prev = &curr->next; curr = nextNode; nextNode = nextNode->next; } // 提前终止:已到链表末尾 if (nextNode == NULL) break; } // 优化:本轮无交换说明已完全有序,提前退出 if (!swapped) break; } // 更新队列的tail指针(排序后尾部可能变化) Passenger* newTail = qPtr->head; while (newTail != NULL && newTail->next != NULL) { newTail = newTail->next; } qPtr->tail = newTail; return 1; // 排序成功 }
可选简化方案:交换节点内容而非指针
如果觉得指针交换逻辑复杂,你可以直接交换两个节点的内容(适合小型结构体),代码会更简洁:
// 替换原交换逻辑的代码块 // 交换两个节点的内容 Passenger temp = *curr; strcpy(curr->name, nextNode->name); curr->passportNumber = nextNode->passportNumber; curr->seatNumber = nextNode->seatNumber; strcpy(nextNode->name, temp.name); nextNode->passportNumber = temp.passportNumber; nextNode->seatNumber = temp.seatNumber; // 无需修改指针,直接移动即可 prev = &curr->next; curr = nextNode; nextNode = nextNode->next;
内容的提问来源于stack exchange,提问作者Andrés Álvarez
相关产品推荐
相关产品推荐

