[英]doubly linked list in C sorting problems
I am trying to write a method that sorts the elements in a doubly linked list.我正在尝试编写一种对双向链表中的元素进行排序的方法。 The list is made up of structs with a forward and backward pointer (flink, blink) to the next element.
该列表由具有指向下一个元素的前向和后向指针(flink、blink)的结构组成。 head->blink should be null, tail->flink should be null (aka not circular).
head->blink 应该是 null,tail->flink 应该是 null(又名不是圆形)。 I tried a selection sort approach but I keep getting a segmentation fault.
我尝试了一种选择排序方法,但我一直遇到分段错误。 I have isolated the problem into the commented lines.
我已将问题隔离到注释行中。 However I included all of my code, the sort method is at the bottom.
但是我包含了我的所有代码,排序方法在底部。
//header (dblLinkList.h)
#include <stdio.h>
#include <stdlib.h>
typedef struct _DblLinkList {
struct _DblLinkList *flink;
struct _DblLinkList *blink;
int num;
} DblLinkList;
struct _DblLinkList *head, *tail;
struct _DblLinkList *init(int nElements);
void sort(struct _DblLinkList *listNode);
void print(struct _DblLinkList *listNode);
//implementation
#include <stdio.h>
#include <stdlib.h>
#include "dblLinkList.h"
int main() {
struct _DblLinkList *list1 = init(2);
printf("-----Head to Tail------\n");
print(list1);
printf("Sorting...\n");
sort(list1);
printf("-----Head to Tail------\n");
print(list1);
}
struct _DblLinkList *init(int nElements) {
struct _DblLinkList *listNode;
int i = 0;
for(i = 0; i < nElements; i++) {
listNode = (struct _DblLinkList *)malloc(sizeof(struct _DblLinkList));
listNode->num = random();
if(head == NULL) {
head = listNode;
listNode->blink = NULL;
} else {
tail->flink = listNode;
listNode->blink = tail;
}
tail = listNode;
listNode->flink = NULL;
}
return listNode;
}
void print(struct _DblLinkList *listNode) {
for(listNode = head; listNode != NULL; listNode = listNode->flink) {
printf("%d\n", listNode->num);
}
}
void sort(struct _DblLinkList *listNode) {
//Not working properly
struct _DblLinkList *listNode2;
struct _DblLinkList *minNode;
struct _DblLinkList *temp = (struct _DblLinkList *)malloc(sizeof(struct _DblLinkList));
//start from the head and traverse the list
for(listNode = head; listNode != NULL; listNode = listNode->flink) {
minNode = listNode;
listNode2 = listNode->flink;
for(;listNode2 != NULL; listNode2 = listNode2->flink) {
if (listNode2->num < minNode->num) {
minNode = listNode2;
}
}
//Problem Lies here vvvvvvvvvvvv
temp->flink = listNode->flink;
temp->blink = listNode->blink;
listNode->blink = listNode2;
listNode->flink = listNode2->flink;
listNode2->flink = temp;
listNode2->blink = temp->blink;
printf("min: %d\n", minNode->num);
}
}
for(;listNode2 != NULL; listNode2 = listNode2->flink)
This loop only exits when listNode2 is NULL
.此循环仅在 listNode2 为
NULL
时退出。 So we've established that at this point listNode2 == NULL
.所以我们已经确定此时
listNode2 == NULL
。
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.
你不应该跟随 NULL 指针,因为混乱和疯狂在它的尽头等待着你。
And here is what you're doing, breaking the second commandment这就是你正在做的,违反第二条诫命
listNode2->flink = temp;
Looks like listNode2
can be NULL
after that for
loop.看起来
listNode2
在for
循环之后可以是NULL
。 You should check that before you try to access listNode2->flink
.在尝试访问
listNode2->flink
之前,您应该检查一下。
I can see a few problems in the code:我可以在代码中看到一些问题:
temp
when you are moving nodes around.temp
块。listnode
away, listnode->flink->blink
(before the move) still points to listnode
.listnode
移开时, listnode->flink->blink
(在移动之前)仍然指向listnode
。listnode->blink->flink
listnode->blink->flink
listnode2
, as linstnode->flink
is now listnode2->flink
, which is not necessarily the old value.listnode2
之间的所有节点,因为linstnode->flink
现在是listnode2->flink
,这不一定是旧值。 This won't cause a crash, but it will leave some nodes unsorted.head
an tail
, so they will probably point to weird nodes when you are done.head
和tail
的特殊处理,所以当你完成时它们可能会指向奇怪的节点。 One trick to handle this seamlessly is to make them into concrete _DblLinkList
structures, so that the code is not riddled with if
statements._DblLinkList
结构,这样代码就不会充满if
语句。 There may be other problems.可能还有其他问题。
FTFY: still pretty ugly hack but should work
--- 2.c 2011-06-07 13:03:48.000000000 -0700
+++ 1.c 2011-06-07 13:49:18.000000000 -0700
@@ -7,7 +7,8 @@
int num;
} DblLinkList;
-struct _DblLinkList *head, *tail;
+struct _DblLinkList *head = NULL;
+struct _DblLinkList *tail = NULL;
struct _DblLinkList *init(int nElements);
void sort(struct _DblLinkList *listNode);
@@ -35,16 +36,16 @@
for(i = 0; i < nElements; i++) {
listNode = (struct _DblLinkList *)malloc(sizeof(struct _DblLinkList));
listNode->num = random();
+ listNode->flink = NULL;
+ listNode->blink = NULL;
if(head == NULL) {
head = listNode;
- listNode->blink = NULL;
} else {
tail->flink = listNode;
listNode->blink = tail;
}
tail = listNode;
- listNode->flink = NULL;
}
return listNode;
}
@@ -55,29 +56,33 @@
}
}
-void sort(struct _DblLinkList *listNode) {
+void sort(struct _DblLinkList *_listNode) {
//Not working properly
- struct _DblLinkList *listNode2;
- struct _DblLinkList *minNode;
- struct _DblLinkList *temp = (struct _DblLinkList *)malloc(sizeof(struct _DblLinkList));
+ struct _DblLinkList* listNode = head;
+ struct _DblLinkList *listNode2 = NULL;
+ struct _DblLinkList *minNode = head;
+ struct _DblLinkList *temp = NULL;
//start from the head and traverse the list
- for(listNode = head; listNode != NULL; listNode = listNode->flink) {
- minNode = listNode;
+ for(; listNode != NULL; listNode = listNode->flink) {
listNode2 = listNode->flink;
for(;listNode2 != NULL; listNode2 = listNode2->flink) {
if (listNode2->num < minNode->num) {
minNode = listNode2;
}
- }
-//Problem Lies here vvvvvvvvvvvv
- temp->flink = listNode->flink;
- temp->blink = listNode->blink;
- listNode->blink = listNode2;
- listNode->flink = listNode2->flink;
- listNode2->flink = temp;
- listNode2->blink = temp->blink;
+ if (listNode->num > listNode2->num) {
+ temp = listNode;
+ listNode = listNode2;
+ temp->flink = listNode2->flink;
+ listNode->flink = temp;
+ listNode->blink = temp->blink;
+ listNode2 = temp;
+ listNode2->blink = listNode;
+ if (head == listNode2)
+ head = listNode;
+ }
printf("min: %d\n", minNode->num);
}
}
+}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.