0

我们在 C 中的 LinkedList 有问题。当我计算列表中应该有多少节点时,我总是得到 1

LL计数:1

这是列表代码的添加、计数和获取最后一个元素:

void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);

newNode = malloc(sizeof(LL));
if(newNode != DEF_NULL)
{
    newNode->ID=-1;
    newNode->TCB=-1;
    newNode->next = DEF_NULL;

    if(!head) head = newNode;
    else tail->next = newNode;      
}   
}

LL * getLastNode(LL * head)
{
    LL *temp = head;
    while(temp->next != DEF_NULL)
    {
        temp = temp->next;
    }
    return temp;
}

CPU_INT32U countLL(LL * head)
{
    CPU_INT32U elements = 0;
    LL * temp = head;
    while(temp->next != DEF_NULL)
    {
        temp = temp->next;
        elements++;
    }
    return elements;
}

它是这样调用的:

addLL(list);
temp = countLL(list);       
Debug_LOG("LL count: %i", temp);

其中 LL * 列表;是一个全局变量,而 temp 在本地范围内。我希望任何人都可以看到我哪里出错了

问候,Sjaak 和 Gerrit

4

4 回答 4

0

在 Windows 上,这个功能没有任何问题 - 奇怪......

ideone 也显示出良好的输出。

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

typedef struct LL{
    struct LL *next;
}LL;

LL * getLastNode(LL * head)
{
    LL *temp = head;
    while(temp->next != NULL)
    {
        temp = temp->next;
    }
    return temp;
}

void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);

newNode = malloc(sizeof(LL));
if(newNode != NULL)
{
    newNode->next = NULL;

    if(!head) head = newNode;
    else tail->next = newNode;      
}   
}

int countLL(LL * head)
{
    int elements = 0;
    LL * temp = head;
    while(temp->next != NULL)
    {
        temp = temp->next;
        elements++;
    }
    return elements;
}

int main() {
    LL *h = malloc(sizeof(*h));
    addLL(h);
    addLL(h);
    addLL(h);
    printf("%d\n", countLL(h)); // prints 3 as expected
}
于 2012-04-25T10:43:03.580 回答
0

CPU_INT32U countLL(LL * head){CPU_INT32U elements = 0;LL * temp = head;while(temp->next != DEF_NULL){temp = temp->next;elements++;}返回元素;}

在此函数中,您将元素变量声明为自动,因此一旦函数退出,它的存储就会被释放,因为内存现在可以自由分配给不同的变量,因此可能会被覆盖,因此以前的 cvalue 会丢失

所以为了避免这种情况,请在声明变量时使用静态......因为静态变量内存只有在整个程序执行后才会被释放,请尝试......

于 2012-04-25T10:54:19.987 回答
0
void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);

这里有一个问题,如果(全局)head 恰好为 NULL,它会被 getLastNode() 函数解引用:

LL * getLastNode(LL * head)
{
    LL *temp = head;
    while(temp->next != DEF_NULL)

temp->next != ...将导致 temp 被取消引用。如果 temp 恰好为 NULL,这将导致 NULL 指针取消引用。(如插入函数的调用。您可以添加额外的测试(或使用指向更清晰的指针的指针):

while(temp && temp->next != DEF_NULL)

更新(以显示指向指针版本的指针更清晰)

#include <stdlib.h>
#include <stdio.h>
#define DEF_NULL NULL
#define CPU_INT32U unsigned

typedef struct link {
        struct link *next;
        } LL;

LL *globhead=NULL;
LL **getTailPP(LL **ppHead);
CPU_INT32U countLL(LL * ptr);
void addLL(LL **ppHead);

void addLL(LL **ppHead)
{
ppHead = getTailPP(ppHead);

*ppHead = malloc(sizeof **ppHead);
    if(*ppHead != DEF_NULL)
    {
        // newNode->ID=-1;
        // newNode->TCB=-1;
        (*ppHead)->next = DEF_NULL;
    }
}

LL **getTailPP(LL **ppHead)
{
    for( ; *ppHead; ppHead = &(*ppHead)->next ) {;}
    return ppHead;
}

CPU_INT32U countLL(LL * ptr)
{
    CPU_INT32U elements = 0;
    for(; ptr != DEF_NULL; ptr=ptr->next) { elements++; }
    return elements;
}

int main()
{
unsigned count;

addLL( &globhead);
count = countLL (globhead);
printf("count = %u\n", count);

addLL( &globhead);
count = countLL (globhead);
printf("count = %u\n", count);

return 0;
}
于 2012-04-25T10:54:43.013 回答
0

我在您的代码中看到了几个问题:

  • 您应该始终通过测试列表指针是否有效(即不为空)来保护您的链表操作
  • 由于分配第一个新项目的方式,您无法将第一个项目分配给空列表:您进行了更改head,但修改不会传播到函数之外。您应该传递一个“指向列表指针的指针”(即 a LL**),它相当于“a 的地址LL*”;看看我是如何调用addLL()的,以及我是如何修改它的原型和head分配的
  • 如果您的列表只有一个块长,那么只有在有后继者时才会计算它,请参阅我如何修改 do / while 条件的顺序

我建议修改后的代码适用于 1、2 或任何列表长度(我刚刚将其更改为CPU_INT32U使用intMinGW 快速编译,我可以使用 typedef'ined):

#include <stdio.h>

#define DEF_NULL 0

typedef struct tagL {
    int ID;
    int TCB;
    struct tagL *next;
} LL;

void addLL(LL ** head);
LL * getLastNode(LL * head);
int countLL(LL * head);

void addLL(LL ** head)
{
    LL *newNode;
    LL *tail = getLastNode(*head);

    newNode = malloc(sizeof(LL));
    if(newNode != DEF_NULL)
    {
        newNode->ID=-1;
        newNode->TCB=-1;
        newNode->next = DEF_NULL;

        if(!*head) 
            *head = newNode;
        else 
            tail->next = newNode;      
    }   
}

LL * getLastNode(LL * head)
{
    LL *temp = head;
    if (head){
        while(temp->next != DEF_NULL)
        {
            temp = temp->next;
        }
    }
    return temp;
}

int countLL(LL * head)
{
    int elements = 0;
    LL * temp = head;
    if (head){
        do {
            temp = temp->next;
            elements++;
        } while(temp != DEF_NULL);
    }
    return elements;
}

int main(int argc, char *argv[]){
    LL *list = 0;

    printf("LL test\n");
    addLL(&list);
    printf("length = %d\n", countLL(list));
    addLL(&list);
    printf("length = %d\n", countLL(list));
    addLL(&list);
    printf("length = %d\n", countLL(list));
}

输出 :

LL test
length = 1
length = 2
length = 3
于 2012-04-25T11:00:08.080 回答