[英]How do I sort a doubly-linked list in ascending order?
I am trying to perform an insertion-sort function on a doubly linked list in the C programming language.我正在尝试在 C 编程语言的双向链表上执行插入排序 function。 When I run the code with this function on a doubly linked list of 1<-->3<-->7<-->4<-->9 I get a sorted output.当我在1<-->3<-->7<-->4<-->9的双向链表上运行带有此 function 的代码时,我得到一个排序的 output。 However, When I run this code on a doubly linked list of 5<-->3<-->7<-->4<-->9 I get a blank output (and yes it still compiles and runs).但是,当我在5<-->3<-->7<-->4<-->9的双向链表上运行此代码时,我得到一个空白 output (是的,它仍然可以编译和运行)。
I cannot figure out why it is returning a blank output when the first node has greater value than the second.当第一个节点的值大于第二个节点时,我无法弄清楚为什么它返回一个空白 output 。 I would guess it has something to do with my if statement?我猜这与我的 if 语句有关?
void insertion_sort_increasing(struct List *list)
{
struct Node *current_node = list->head; //initialize current_node
struct Node *tempA;
struct Node *tempB;
struct Node *tempC;
struct Node *tempD;
if (current_node == NULL) {
printf("Empty List.");
} else {
current_node = current_node->next;
while (current_node != NULL) { //iterates doubly linked list
if (current_node->prev->StudentID > current_node->StudentID) {
tempA = current_node; //(3 in this case)
tempB = current_node->prev->prev; //(NULL in this case)
tempC = tempA->next->prev;
tempD = tempB->next;
tempA->next->prev = tempA->prev; // 5<--7
tempB->next->prev = tempC; // 3<--5
tempB->next = tempA->prev->next; // NULL-->3
tempA->prev->next = tempA->next; // 5-->7
tempA->next = tempD; // 3-->5
tempA->prev = tempD->prev; // NULL<--3
if (tempB == NULL) {
list->head = tempB->next; // 3 = head
}
}
current_node = current_node->next;
}
}
}
There are multiple problems in your code:您的代码中有多个问题:
tempB
is null, ie: if the 2 initial nodes of the list should be swapped.如果tempB
是 null,则代码崩溃,即:如果应该交换列表的 2 个初始节点。list->head
should be updated if the first node changes.如果第一个节点发生变化,则应该更新list->head
。tempC
that is equal to tempA
, and the initial order is not tempA
-> tempB
-> tempC
-> tempD
.临时变量名称令人困惑,尤其是tempC
等于tempA
,并且初始顺序不是tempA
-> tempB
-> tempC
-> tempD
。Here is a modified version:这是修改后的版本:
void insertion_sort_increasing(struct List *list)
{
struct Node *current_node = list->head;
while (current_node != NULL) {
struct Node *next = current_node->next;
while (current_node->prev && current_node->prev->StudentID > current_node->StudentID) {
// swap current_node and its predecessor (tempC and tempB)
struct Node *tempA = current_node->prev->prev;
struct Node *tempB = current_node->prev;
struct Node *tempC = current_node;
struct Node *tempD = current_node->next;
if (tempA) {
tempA->next = tempC;
} else {
list->head = tempC;
}
tempC->prev = tempA;
tempC->next = tempB;
tempB->prev = tempC;
tempB->next = tempD;
if (tempD) {
tempD->prev = tempB;
} else {
list->tail = tempB;
}
}
current_node = next;
}
}
You need to learn to separate concerns in your code.您需要学习在代码中分离关注点。 An insertion sort takes an input list or array and returns an output list or array.插入排序接受输入列表或数组并返回 output 列表或数组。 So to start with, you need a function that either takes a List**
and returns void
, or it takes a List*
and returns a List*
.因此,首先,您需要一个 function ,它要么接受List**
并返回void
,要么接受List*
并返回List*
。 Logically you need to do three things correctly, 1) iterate over the input list, 2) Remove a node from the input list without breaking 1, 3) insert into the output list at the correct position for the sort order.从逻辑上讲,您需要正确地做三件事,1)遍历输入列表,2)从输入列表中删除一个节点而不破坏 1、3)在正确的 position 列表中插入 output 列表以进行排序。 That amounts to three functions.这相当于三个功能。
List *InsertionSort(List * pList) {...}
List *SortedInsert(List *pList, List *pNode) {...}
List *Remove(List *pNode) {...}
InsertionSort
just loops over the it's input, calling Remove
, without loosing track of the head or tail pointer, depending on which way you're moving through the list, and then calls SortedInsert
with the node it just removed from the head or tail of the pList. InsertionSort
只是循环它的输入,调用Remove
,而不会丢失头或尾指针的轨道,具体取决于您在列表中移动的方式,然后使用刚刚从头或尾删除的节点调用SortedInsert
列表。 SortedInsert
then iterates through pList
looking for the correct place to insert pNode
and then returns the new head of the list, which might just be pNode
. SortedInsert
然后遍历pList
寻找插入pNode
的正确位置,然后返回列表的新头部,它可能只是pNode
。
It's just easier to think about one operation at a time, and the code you write will be simpler and easier to understand and debug.一次只考虑一项操作更容易,您编写的代码将更简单,更易于理解和调试。 In fact, you can test SortedInsert
first, to make sure it's working, then test Remove
, and then move on to to InsertionSort
.事实上,您可以先测试SortedInsert
以确保它正常工作,然后测试Remove
,然后继续进行InsertionSort
。 You'll need to learn how to use your debugger and make yourself familiar with stepping through your code and checking the state of your variables.您需要学习如何使用调试器并熟悉如何逐步执行代码并检查变量的 state。 A fourth function, PrintList
is probably on order here as well.第四个 function, PrintList
也可能在这里订购。
I am not going to write a bunch of code or be really explicit about the algorithm details, because you can get that with an SO or Google search, and this seems like an obvious homework assignment.我不打算写一堆代码或对算法细节非常明确,因为你可以通过 SO 或谷歌搜索得到,这似乎是一个明显的家庭作业。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.