【问题标题】:How do I correctly add to an array of linked lists?如何正确添加到链表数组?
【发布时间】:2014-11-19 06:54:43
【问题描述】:

我正在制作一个由链表实现的图表,但我发现自己有点困惑,因为我确定我没有正确遍历链表。

// A structure to represent an adjacency list node
typedef struct AdjListNode
{
    char data;
    int distance;
    struct AdjListNode* next;
} AdjListNode;

// A structure to represent an adjacency list
typedef struct AdjList
{
    char data;
    struct AdjListNode* head;  // pointer to head node of list
} AdjList;

// A structure to represent a graph. A graph is an array of adjacency lists.
// Size of array will be the number of vertices in graph.
typedef struct Graph
{
    int NumberOfNodes;
    struct AdjList* array;
} Graph;

所以我正在制作一个具有数组的图,并且数组的每个元素都是链表的头。

但是,当我尝试输出所有元素时,它只打印头部旁边的元素,例如:

A->B5
B->E6
C->A8
D->C2
E->D7

所以在将它们添加到链表时会出错,因为它应该是

A->B5->D5-C7
B->E6->E4
C->A8
D->C2->B6->A2
E->D7

这是函数的 sn-p,它将节点添加到图中我相信 else 语句有错误

    for(i =0; i < G->NumberOfNodes ; i++)
    {
        if(G->array[i].data == from)
        { // if the letter from the primary array matches the letter that needs to be added to
            if(G->array[i].head == NULL)
            { // if the head node of the linked list is empty simply just and the element there
                G->array[i].head = malloc(sizeof(AdjListNode));
                G->array[i].head->data = to;
                G->array[i].head->distance = number;
                G->array[i].head->next = NULL;
            }
            else
            {    // if the head is not empty then this will find another position for it
                AdjListNode* looker;

                looker = G->array[i].head;

                while(looker != NULL)
                {
                    looker = looker->next; // pointing to the next position
                }

                looker = malloc(sizeof(AdjListNode)); // placing the element on that position
                looker->data = to;
                looker->distance = number;
                looker->next = NULL;

                free(looker);
            }
        }
    }

【问题讨论】:

  • 你有没有调试过?
  • 不,我不知道如何完全使用 de gdb...但我几乎 90% 确定错误出在 addEdge 函数上,即使用“looker”变量的 else 语句
  • 感谢 UniCell!对于那个编辑

标签: c algorithm pointers linked-list graph-algorithm


【解决方案1】:

这是错误的:

AdjListNode* looker;
looker = G->array[i].head;
while(looker != NULL){
    looker = looker->next; // pointing to the next position
}

looker = malloc(sizeof(AdjListNode)); // placing the element on that position
looker->data = to;
looker->distance = number;
looker->next = NULL;
free(looker);

它绝对不会对G-&gt;array[i].head 引用的链表进行任何更改。它遍历一个指向链表末尾的指针(最多有一个节点)。然后它什么都不做(怎么可能?你所拥有的只是一个什么都没有的指针),然后简单地分配一些内存,设置节点,然后立即释放它。

如果你想链接到链表的尾部,你必须找到链表中的最后一个指针。一种方法是使用双指针,作为奖励,它也可以减轻您的特殊空头情况。您的整个 for 循环至少看起来很简单:

for(i =0; i < G->NumberOfNodes ; i++)
{
    if(G->array[i].data == from)
    {
        AdjListNode** pp = &(G->array[i].head);
        while (*pp)
            pp = &(*pp)->next;

        *pp = malloc(sizeof(**pp));
        (*pp)->data = to;
        (*pp)->distance = number;
        (*pp)->next = NULL;
    }
}

这是关键每个插槽中的head 指针在进入此弹幕之前为 NULL,希望原因很明显。

祝你好运。

【讨论】:

  • 我确实知道那里出了点问题!您的代码完美运行。但是,您能向我解释一下为什么双指针会这样做吗?我认为双指针用于二维数组..
  • @ReynaldoGonzalez 指向指针的指针与任何其他指针没有什么不同;它保存某物的地址(在这种情况下是指针而不是某个数据节点)。代码使用它遍历链表,保存我们要检查 NULL 的每个指针的地址(包括头指针)。当我们的指针指向的指针为 NULL 时,我们已经到达列表的末尾,我们正在寻址的指针就是它终止的地方。从那里,我们只需分配一个新节点,将其分配给该指针(通过取消引用*pp),我们就完成了。
  • 非常感谢克雷格。我敢打赌,您正在为非常好的软件公司工作。自明年毕业以来,我正在学习面试问题。
猜你喜欢
  • 2014-06-10
  • 1970-01-01
  • 1970-01-01
  • 2017-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多