двусвязный список в задачах сортировки C - PullRequest
0 голосов
/ 07 июня 2011

Я пытаюсь написать метод, который сортирует элементы в двусвязном списке.Список состоит из структур с прямым и обратным указателем (мигать, мигать) на следующий элемент.head-> blink должен быть нулевым, tail-> flink должен быть нулевым (иначе не круговым).Я попробовал подход сортировки по выбору, но я продолжаю получать ошибку сегментации.Я выделил проблему в комментариях.Однако я включил весь свой код, метод сортировки находится внизу.

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

Ответы [ 4 ]

3 голосов
/ 07 июня 2011
for(;listNode2 != NULL;  listNode2 = listNode2->flink)

Этот цикл завершается только тогда, когда listNode2 равен NULL.Итак, мы установили, что в этот момент listNode2 == NULL.

Ты не должен следовать указателю NULL, потому что хаос и безумие ждут тебя в его конце.

Ивот что вы делаете, нарушая вторую заповедь

listNode2->flink = temp;
2 голосов
/ 08 июня 2011

Я вижу несколько проблем в коде:

  1. Вы продолжаете вставлять один и тот же кусок памяти, temp, когда перемещаете узлы вокруг.
  2. Когда выудаление listnode, listnode->flink->blink (до перемещения) по-прежнему указывает на listnode.
  3. То же, что и # 2, но для listnode->blink->flink
  4. При перемещении узла узла вы потенциально можетепропустите все узлы между старой позицией и listnode2, поскольку linstnode->flink теперь равно listnode2->flink, что не обязательно является старым значением.Это не приведет к сбою, но некоторые узлы останутся не отсортированными.
  5. При перемещении узлов я не видел никакой специальной обработки head и tail, поэтому они, вероятно, будут указывать настранные узлы, когда вы закончите.Один из способов справиться с этим - сделать из них конкретные _DblLinkList структуры, чтобы код не был пронизан операторами if.

Могут быть и другие проблемы.

2 голосов
/ 07 июня 2011

Похоже, listNode2 может быть NULL после этого цикла for. Вы должны проверить это, прежде чем пытаться получить доступ к listNode2->flink.

0 голосов
/ 08 июня 2011
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);
         }
     }
+}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...