你能告诉我这个错了吗?

时间:2013-04-18 01:20:16

标签: c

需要帮助请请帮助 我的代码编译得很好,但是当我运行它时会出现一个seg错误,我不明白为什么。我已经多次查看代码,但仍然不知道问题出在哪里。需要帮助。

void insertionSort(listNode ** listPtr, listNodeCompareFcn compare)
{

  listNode * sorted = *listPtr; 
  listNode * swapper; 
  listNode * prev; 
  int swapped; 

  while(sorted != NULL)
  {

    swapper = sorted -> next;
    prev = findprev(*listPtr, swapper);
    swapped = 0; 

    while(swapper != NULL && prev != NULL && swapper != *listPtr && compare(swapper,prev))

    { 
        swapNodes(*listPtr, prev, swapper); 
        prev = findprev(*listPtr, swapper); 
        swapped = 1;
    }

         if (!swapped) sorted = sorted -> next;

  }

}


static listNode * findprev(listNode * head, listNode * ptr){

    listNode * current = head;

    while (current -> next != NULL){
        if ((current -> next) == ptr) return current;
        current = current -> next;
   }    

  return NULL; 

} 

void swapNodes(listNode * head, listNode * l1, listNode * l2){

  listNode * prev = findprev(head, l1);
  prev -> next = l2;
  l1 -> next = l2 -> next;
  l2 -> next = l1; 

}

1 个答案:

答案 0 :(得分:2)

我评论道:

  

我已经在SSCCE上做了足够的工作,知道问题的主要部分是你对列表的负责人不够小心。如果交换头节点和下一个节点,则需要更新头节点指针,否则会丢失列表的前面。我可以肯定的是,这只是麻烦的一个组成部分[实际上是整个麻烦]。给定有效列表,findprev()函数可以正常工作。我认为,swapNodes()insertionSort()都不能给出干净的健康状况(尚未!)。例如,如果findprev()返回NULL,swapNodes()会愉快地取消引用NULL指针;崩溃!

以下是您的代码的SSCCE版本,并使用有关上述评论中标识的swapNodes()修补程序的反向渠道信息进行了更新。 compare()函数原来是C ++风格的比较器,而不是C风格的比较器;也就是说,如果节点1在节点2之前,则返回true,否则返回false(而C风格比较器返回-1,0,+ 1 - 或严格地,负,零,正 - 小于,等于,大于)。只需修复swapNodes() - 接口和代码更改 - 以及正确的比较器语义,列表就可以正确排序。几乎没有详尽的测试,但是一个良好的开端。

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct listNode listNode;
struct listNode
{
    int datum;
    listNode *next;
};

typedef int (*listNodeCompareFcn)(const listNode *n1, const listNode *n2);
//static void swapNodes(listNode *head, listNode *l1, listNode *l2);
static void swapNodes(listNode **head, listNode *l1, listNode *l2);
static listNode *findprev(listNode *head, listNode *ptr);

static int node_compare(const listNode *n1, const listNode *n2)     // SSCCE
{
    assert(n1 != 0 && n2 != 0);
    printf("Compare: %2d and %2d\n", n1->datum, n2->datum);
    if (n1->datum < n2->datum)
        return 1;
//    if (n1->datum < n2->datum)
//        return -1;
//    else if (n1->datum > n2->datum)
//        return +1;
    else
        return 0;
}

static void insertionSort(listNode **listPtr, listNodeCompareFcn compare)
{
    listNode *sorted = *listPtr;

    while (sorted != NULL)
    {
        listNode *swapper = sorted->next;
        listNode *prev = findprev(*listPtr, swapper);
        int swapped = 0;

        while (swapper != NULL && prev != NULL && swapper != *listPtr && compare(swapper, prev))
        {
            //swapNodes(*listPtr, prev, swapper);
            swapNodes(listPtr, prev, swapper);
            prev = findprev(*listPtr, swapper);
            swapped = 1;
        }

        if (!swapped)
            sorted = sorted->next;
    }
}

static listNode *findprev(listNode *head, listNode *ptr)
{
    listNode *current = head;
    assert(current != 0);

    while (current->next != NULL)
    {
        if (current->next == ptr)
            return current;
        current = current->next;
    }

    return NULL;
}

// Update via email
void swapNodes(listNode **listPtr, listNode *l1, listNode *l2)
{
    listNode *prev = findprev(*listPtr, l1);
    if (prev == NULL)
    {
        l1->next = l2->next;
        *listPtr = l2;
        l2->next = l1;
    }
    else
    {
        prev->next = l2;
        l1->next = l2->next;
        l2->next = l1; 
    }
}

/*
static void swapNodes(listNode *head, listNode *l1, listNode *l2)
{
    listNode *prev = findprev(head, l1);
    prev->next = l2;
    l1->next = l2->next;
    l2->next = l1;
}
*/

static listNode *node_insert(listNode *head, int datum)     // SSCCE
{
    listNode *node = malloc(sizeof(*node));
    node->datum = datum;
    node->next = head;
    return node;
}

static void print_list(const char *tag, const listNode *list)       // SSCCE
{
    printf("%-8s", tag);
    while (list != 0)
    {
        printf(" -> %2d", list->datum);
        list = list->next;
    }
    putchar('\n');
}

int main(void)      // SSCCE
{
    static const int unsorted[] = { 29, 3, 14, 2, 91, 87, 13, 29, 1 };
    enum { NUM_VALUES = sizeof(unsorted) / sizeof(unsorted[0]) };
    listNode *head = 0;

    print_list("Empty:", head);
    for (int i = 0; i < NUM_VALUES; i++)
    {
        head = node_insert(head, unsorted[i]);
        print_list("Added:", head);
    }

    for (listNode *curr = head; curr != 0; curr = curr->next)
    {
        listNode *prev = findprev(head, curr);
        if (prev == 0)
            printf("%2d - no prior node\n", curr->datum);
        else
            printf("%2d - prior node %2d\n", curr->datum, prev->datum);
    }

    print_list("Before:", head);
    insertionSort(&head, node_compare);
    print_list("After:", head);

    return 0;
}

来自SSCCE的输出(包括诊断):

Empty:  
Added:   -> 29
Added:   ->  3 -> 29
Added:   -> 14 ->  3 -> 29
Added:   ->  2 -> 14 ->  3 -> 29
Added:   -> 91 ->  2 -> 14 ->  3 -> 29
Added:   -> 87 -> 91 ->  2 -> 14 ->  3 -> 29
Added:   -> 13 -> 87 -> 91 ->  2 -> 14 ->  3 -> 29
Added:   -> 29 -> 13 -> 87 -> 91 ->  2 -> 14 ->  3 -> 29
Added:   ->  1 -> 29 -> 13 -> 87 -> 91 ->  2 -> 14 ->  3 -> 29
 1 - no prior node
29 - prior node  1
13 - prior node 29
87 - prior node 13
91 - prior node 87
 2 - prior node 91
14 - prior node  2
 3 - prior node 14
29 - prior node  3
Before:  ->  1 -> 29 -> 13 -> 87 -> 91 ->  2 -> 14 ->  3 -> 29
Compare: 29 and  1
Compare: 13 and 29
Compare: 13 and  1
Compare: 87 and 29
Compare: 91 and 87
Compare:  2 and 91
Compare:  2 and 87
Compare:  2 and 29
Compare:  2 and 13
Compare:  2 and  1
Compare: 14 and 91
Compare: 14 and 87
Compare: 14 and 29
Compare: 14 and 13
Compare:  3 and 91
Compare:  3 and 87
Compare:  3 and 29
Compare:  3 and 14
Compare:  3 and 13
Compare:  3 and  2
Compare: 29 and 91
Compare: 29 and 87
Compare: 29 and 29
After:   ->  1 ->  2 ->  3 -> 13 -> 14 -> 29 -> 29 -> 87 -> 91