如何正确添加到链接列表数组?

时间:2014-11-19 06:54:43

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

我正在创建一个由链表实现的图表,我发现自己有点混乱,因为我确定我没有正确遍历链接列表。

// 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

这是函数的一个片段,它将节点添加到图表中我认为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);
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

这是错误的:

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

critical 每个插槽中的head指针在进入此弹幕之前是NULL,希望显而易见。

祝你好运。