双向链表冒泡排序实现:TrainCar车厢排序代码修复与优化求助
代码问题分析
- 外层循环每轮执行完成后,没有重置
current指针为链表头节点head,也没有重置计数变量count为1。第一轮遍历结束后current已经指向链表尾节点,后续所有外层循环的遍历逻辑都不会执行,排序仅会进行一轮,无法得到正确结果。 - 升序、降序逻辑代码重复度极高,冗余写法不利于后续维护。
- 未添加冒泡排序的提前终止逻辑,链表已经有序的场景下仍会执行完所有循环,存在不必要的性能损耗。
- 未添加边界判断,空链表或仅含一个节点的场景下不需要执行排序逻辑。
修复后的代码(兼容原swapCar调用逻辑)
void sortTrain(TrainCar* head, bool ascending) { int size = getlength(head); // 边界判断:空链表或只有1个节点无需排序 if (size <= 1) { return; } for(int i = 0; i < size - 1; i++) { // 每轮遍历前重置指针和计数 TrainCar* current = head; int count = 1; bool swapped = false; while(current->next != NULL) { // 整合升序降序判断,避免重复代码 bool needSwap = (ascending && current->load > current->next->load) || (!ascending && current->load < current->next->load); if (needSwap) { swapCar(head, count, count + 1); swapped = true; } count++; current = current->next; } // 本轮无交换说明已完全有序,提前退出 if (!swapped) { break; } } }
更高性能的替代实现
如果允许直接修改节点的载荷属性,不需要调用swapCar交换节点位置,可以使用下面的版本,省去了按位置查找节点的开销,排序效率更高:
void sortTrain(TrainCar* head, bool ascending) { // 边界判断 if (head == NULL || head->next == NULL) { return; } bool swapped; TrainCar* cur; // 标记已排序完成的尾部边界 TrainCar* sortedTail = NULL; do { swapped = false; cur = head; while (cur->next != sortedTail) { bool needSwap = (ascending && cur->load > cur->next->load) || (!ascending && cur->load < cur->next->load); if (needSwap) { // 直接交换载荷值,无需修改链表指针 int temp = cur->load; cur->load = cur->next->load; cur->next->load = temp; swapped = true; } cur = cur->next; } // 更新已排序的尾部边界 sortedTail = cur; } while (swapped); }
内容的提问来源于stack exchange,提问作者misscubic
相关产品推荐
相关产品推荐

