【问题标题】:Need some assistance with sorting a linked list在对链表进行排序时需要一些帮助
【发布时间】:2016-07-06 00:01:33
【问题描述】:

我正在做一个学校作业,我正在制作一个 int 链表,它应该具有对其进行排序的功能。我很确定我根据输出得到了正确的链接。排序函数应该交换节点,而不是值。我收到分段错误(核心转储)消息,不确定它的含义或原因。我正在寻求有关为什么它不起作用的帮助。我对指针仍然很糟糕,所以我认为这是一个问题。我的排序也是插入排序

typedef struct node {
    int data;
    struct node *next;
    struct node *prev;
} node;

node *pHead = NULL; // head of list
node *pCurr = NULL; // current node
int count = 0;

void create(int data) {

    node *pNode = (node*) malloc(sizeof(node));
    pNode->data = data;
    pNode->next = NULL;
    pNode->prev = NULL;


    pHead = pCurr = pNode;
    count += 1;
}

void add(int data) {
    if (pHead == NULL) {
        return create(data);
    }

    node *pNode = (node*) malloc(sizeof(node));
    pNode->data = data;
    pNode->next = NULL;

    pNode->prev = pCurr;
    pCurr->next = pNode;
    pCurr = pNode;

    count += 1;
}

int size() {
    return count;
}

void print() {
    node *pNode = pHead;
    while (pNode != NULL) {
        printf("[%d]->", pNode->data);
        pNode = pNode->next;
    }
    printf("\n");
}

void sort(node *current) {

    pHead = current;
    node *pInsert = pHead;
    current = current->next;
    int i, j;
    for (i = 0; i < size(); i++) {
        for (j = i; j > 0; j--) {
            if (current->data >= pInsert->data) {
                node *pTemp = current;
                current = pInsert;
                pInsert = pTemp;
            }
            pInsert = pInsert->prev;
        }
        current = current->next;
    }

    print();
}

【问题讨论】:

  • 快速浏览一下,我发现您没有 NULL 保护,因此您可以尝试取消引用空指针
  • 您实际上并没有交换节点。您只是在更改 currentpInsert 指向的内容。
  • 在受交换影响的所有节点中更改 nextprev 指向的内容。
  • Current= current-&gt;next 如果您的当前节点是最后一个节点,稍后将导致段错误。在 if (current-&gt;data &gt;= pInsert-&gt;data) 处添加一个 NULL 指针保护
  • 是的,现在当你处理链表时,尤其是当你有 prev/next 指针时,要移动东西,你需要一个 delete 函数和一个 insert 函数。删除函数基本上采用一个节点,并执行如下操作:node-&gt;prev-&gt;next = node-&gt;next 应该有效地将其从列表中删除。然后你的插入函数看起来像nodeIWantToInsert-&gt;next = insertionPoint-&gt;next, nodeIWantToInsert-&gt;previous = insertionPoint, nodeIWantToInsert-&gt;next-&gt;previous = nodeIWantToInsert

标签: c


【解决方案1】:

要弄清楚如何交换链表中的相邻节点,画一张图很有指导意义。想象节点 A、B、C、D 以链表顺序排列,其中下一个指针是绿线,前一个指针是红线。然后,想象一下如果您只是将 B 和 C 节点移动到彼此的位置,电线会发生什么情况。

现在,弄清楚你必须做哪些指针操作才能让图片看起来又漂亮又漂亮。

【讨论】:

    【解决方案2】:
    void sort(node *current) {
    
        node *pTemp, *pInsert = current;
        current = current->next;
        int i, j;
        for (i = 0; i < size(); i++) {
            for (j = i; j > 0; j--) {
             if (current != NULL && pInsert != NULL && current->data >= pInsert->data) {
    
    /*start delete node*/
              if (pInsert->prev != NULL)
               pInsert->prev->next = pInsert->next;
              if (pInsert->next != NULL)
               pInsert->next->prev = pInsert->prev 
    /*end delete node*/
    /*start add node*/
              pInsert->next = current->next;
              pInsert->prev = current;
              if (current->next != NULL)
               current->next->prev = pInsert;
              current->next = pInsert;
    /*end add node*/
                }
                pInsert = pInsert->prev;
            }
            current = current->next;
        }
    
        print();
    }
    

    试试这个。基本上你从当前位置删除你的节点,通过让前一个节点的下一个指针跳过有问题的节点并指向后面的节点,然后你让下一个节点跳过有问题的节点并指向前一个节点。

    然后你插入你的节点,让你有问题的节点的下一个指针指向你的插入点的下一个节点......(在谈论下一个的下一个/前一个的下一个时会有点混乱)。

    重要:另外,在处理这些指针时,请确保进行 NULL 检查!

    【讨论】:

    • 通过更难阅读的多个取消引用摆脱了它;),即node-&gt;next-&gt;prev
    • @AdamWolf 这不是唯一的问题。这也意味着列表的失败,该列表已排序,更改了哪个节点是头。调用者永远不会看到这种变化。
    • 哦,是的,我也因此删除了那个位,加入查找头/尾功能可能不会有什么坏处。即搜索直到你打到空
    • 我收到了一条核心转储消息?使用 while 循环似乎可以修复它,但打印不正确。主 while 循环正在执行 current->next != null 而内部 while 循环正在执行 pInsert->prev != null
    • 哎呀,对不起,我已经用所有需要的 NULL 检查更新了它
    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-27
    • 2019-12-16
    • 2021-11-08
    • 2019-12-25
    • 2014-06-29
    相关资源
    最近更新 更多