2011-06-07 113 views
0

我想写一个方法,在双向链表中排序元素。该列表由具有向前和向后指针(闪烁,闪烁)到下一个元素的结构组成。 head-> blink应该为null,tail-> flink应该为null(又称非圆形)。我尝试了一种选择排序方法,但我一直在收到分段错误。我已将问题隔离到注释行中。但是,我包括了我的所有代码,排序方法在底部。在C排序问题双向链表

//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); 
     } 
    } 
+0

您标记了这个C和C++ ...但它看起来像C。这是什么,只是要明确清楚? – 2011-06-07 19:53:39

+0

如果您在调试器中运行您的程序,您应该确定*确切*哪条线触发了seg-fault。然后,您应该能够检查当时的变量值,并将它们与您期望的值进行比较。 – 2011-06-07 19:55:07

+0

同意,这看起来像编译C. – 2011-06-07 19:55:46

回答

2

看起来listNode2可以NULLfor循环之后。在尝试访问listNode2->flink之前,您应该检查一下。

+0

不是程序的唯一问题,但它看起来像是我的段错误的来源。 – 2011-06-07 20:02:18

3
for(;listNode2 != NULL; listNode2 = listNode2->flink) 

这个循环只有当listNode2是NULL退出。所以我们已经确定在这一点上listNode2 == NULL

不可跟随NULL指针 为混乱和疯狂等待 你在它的末端。

这里是你在做什么,突破了第二诫

listNode2->flink = temp; 
+0

@Arthur Shipkowski良好的呼唤;发现另一个:)) – cnicutar 2011-06-07 20:02:41

+0

嘿,在这里我删除了我的评论,认为你刚刚有一个错字。 – 2011-06-07 20:04:19

2

我可以看到在代码中的几个问题:

  1. 你保持插入相同的内存块,temp当你移动节点。
  2. 当您移动listnode时,listnode->flink->blink(移动前)仍指向listnode
  3. 同#2,但listnode->blink->flink
  4. 当您移动listnode,你可能跳过旧的位置和listnode2之间的所有节点,如linstnode->flink现在listnode2->flink,这并不一定是旧值。这不会导致崩溃,但它会留下一些未排序的节点。
  5. 当移动节点时,我没有看到headtail的任何特殊处理,所以当你完成后它们可能会指向奇怪的节点。处理这种无缝操作的一个诀窍是使它们成为具体的_DblLinkList结构,以便代码不会与if陈述混杂在一起。

可能还有其他问题。

0
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); 
     } 
    } 
+} 
+0

是的!谢谢。我知道我在正确的轨道上,我只是无法弄清楚改变指针 – Matt 2011-06-07 21:06:06

+0

的顺序,除非我说得太快,它不适用于N个节点。 – Matt 2011-06-07 21:07:47

+0

我应该说,它的顺序,但并不是所有的节点都不存在之后。 – Matt 2011-06-07 21:09:48