简体   繁体   English

链表获取分段错误

[英]Linked list- getting segmentation fault

void AlternatingSplit(struct Node* source, struct Node** aRef, 
                        struct Node** bRef) 
{
/* split the nodes of source to these 'a' and 'b' lists */
struct Node* a ; 
struct Node* b;

struct Node* current = source;
if(current){
    a=current;
    b=current->next;
    current=b->next;
    a->next=NULL;
    b->next=NULL;
}

while(current) {    
    a->next=current;
    b->next=current->next;

    if(b)
        current=b->next;

    b=b->next;
    a=a->next;
}

*aRef = a;
*bRef = b;
}

I am getting segmentaton fault here i dont know why pls help. 我在这里遇到了segmentaton错误,我不知道为什么请帮助。

This question is to alternating split linkedlist nodes. 这个问题是交替分割链表节点。 I m using two pointers a and b and adding to it alternatingly but its giving error . 我使用两个指针a和b并交替添加它,但是给出了错误。 pls help me 请帮助我

Like most linked-list rearrangement exercises, pointers to pointers make the job much , much easier. 像大多数链表重排练习一样,指向指针的指针使工作变得非常容易。 The point of this exercise it to flex your ability to change the next pointers without ever changing the data values of said-same. 本练习的目的在于,您可以灵活地更改next指针,而不必更改相同的数据值。 Pointers to pointers are an excellent way to do that in C. 指向指针的指针是用C语言做到这一点的绝佳方法。

This is especially trivial because you were already provided the target pointer-to-pointer arguments that we can reuse for building each list. 这是特别琐碎的,因为已经为您提供了目标指针到指针参数,我们可以重复使用这些参数来构建每个列表。 How that works is best understood by demonstrating a technique for building a forward-chained linked list using a single head pointer and a pointer to pointer p : 通过演示使用单头指针和指针p的指针构建前向链表的技术,可以最好地理解其工作原理:

struct Node *head, **pp = &head;
for (int i = 1; i <= 20; ++i)
{
    *pp = malloc(sizeof **pp);
    (*pp)->data = i;
    pp = &(*pp)->next;
}
*pp = NULL;

Yes, it needs error checking, but the algorithm is what to focus on here. 是的,它需要进行错误检查,但是这里要重点介绍算法。 This code uses only pp to build the actual list. 此代码仅使用pp来构建实际列表。 The rule is this: pp is a pointer to pointer to Node , and always holds the address of the next pointer to Node to populate. 规则是这样的: pp是指向Node指针,并且始终保存要填充的下一个Node的地址。 That's what pointers to pointers do: hold addresses of pointers. 那就是指针的指针所做的事情:保存指针的地址。 In this case pp initially holds the address of the head pointer. 在这种情况下, pp最初保留了头指针的地址。 With each new node added pp takes the address of the next pointer of the previously just-added node. 在添加每个新节点后, pp占用先前刚刚添加的节点的next指针的地址。 Makes sense, right? 有道理吧? That will be the next pointer where we want to hang the next node. 那将是我们要挂起下一个节点的下一个指针。 This process continues until we finish the loop. 这个过程一直持续到我们完成循环为止。 At that pointer pp holds the address of the last node's next pointer, which we set to NULL to terminate the list. 在该指针pp保存最后一个节点的next指针的地址,我们将其设置为NULL以终止列表。

Now, knowing what we learned above, consider this: 现在,了解了我们上面学到的知识后,请考虑以下问题:

void AlternatingSplit(struct Node* source, struct Node** a, struct Node** b)
{
    while (source)
    {
        *a = source;
        a = &(*a)->next;

        source = source->next;
        if (source)
        {
            *b = source;
            b = &(*b)->next;
            source = source->next;
        }
    }

    *a = *b = NULL;
}

Example

A short example using both the forward-chaining build algorithm I showed first, and the split algorithm I showed after, appears below. 下面显示了一个简短的示例,该示例同时使用了我首先显示的正向链构建算法和我之后显示的split算法。 Some utility functions for printing the list are included. 包括一些用于打印列表的实用程序功能。 I leave freeing the lists (there are two now, remember to walk both and free each node) as an exercise for you: 我将释放这些列表(现在有两个列表,请记住同时走路并释放每个节点)作为练习:

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

struct Node
{
    int data;
    struct Node *next;
};

void AlternatingSplit(struct Node* source, struct Node** a, struct Node** b)
{
    while (source)
    {
        *a = source;
        a = &(*a)->next;

        if ((source = source->next))
        {
            *b = source;
            b = &(*b)->next;
            source = source->next;
        }
    }

    *a = *b = NULL;
}

void PrintList(struct Node const *p)
{
    while (p)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    fputc('\n', stdout);
}


int main(void)
{
    struct Node *head, **pp = &head;
    for (int i = 1; i <= 20; ++i)
    {
        *pp = malloc(sizeof **pp);
        (*pp)->data = i;
        pp = &(*pp)->next;
    }
    *pp = NULL;

    PrintList(head);

    struct Node *a = NULL, *b = NULL;
    AlternatingSplit(head, &a, &b);

    PrintList(a);
    PrintList(b);

    return EXIT_SUCCESS;
}

Output 产量

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 3 5 7 9 11 13 15 17 19
2 4 6 8 10 12 14 16 18 20

There are few errors in your code - 您的代码中几乎没有错误-

  • Trying to access node->next , without checking whether node exists or not . 尝试访问node-> next,而不检查node是否存在。
  • Not tackling the corner cases depending on the length of linked list (ie if length (linked list) < 3 ) 不根据链接列表的长度处理极端情况(即,如果length(链接列表)<3)
  • And then comes the blunder , you are trying to make the new linked lists and then in the end aRef and bRef is assigned to the last node in their respective linked lists. 然后是大错,您正在尝试创建新的链表,最后将aRef和bRef分配给它们各自链表中的最后一个节点。

Try to deal with these problems and for reference you can see the code below. 尝试解决这些问题,请参阅下面的代码以供参考。

void AlternatingSplit(struct Node* source, struct Node** aRef, 
                    struct Node** bRef) 
{

struct Node* a,b; 
struct Node* current = source;

if(current){
       a=current;
       b=current->next;
       // moving 'current' one step at a time will secure the code from crashing for corner cases
       current = current->next;
       if(b)
             current=b->next;
       a->next=NULL;
       b->next=NULL;

       //link aRef bRef right here
       *aRef = a;
       *bRef = b;
       }

 else {
      *aRef = source; // Null
      *bRef = source; // Null
      return;
      }

while(current) 
{
     a->next=current;
     a=a->next;
     b->next=current->next;
     b=b->next;
     current=current->next;
     if(b){
          current = b->next;
          }
 }
 b->next = NULL;
 a->next = NULL;

} 

Hope this will help . 希望这会有所帮助。

Keep asking , keep growing :) 不断询问,不断发展:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM