填写C中的链接列表后的额外节点

时间:2019-07-12 18:05:16

标签: c memory linked-list

我有一个整数(例如123),我需要将其反向存储(逐位)在链接列表中。 但我似乎在列表的末尾多了一位数字。 例如:807需要存储为“ 7-> 0-> 8” 但是我的输出是“ 7-> 0-> 8-> -1094795586'。

这是针对leetcode问题“加两个数字”。

//我需要在结果中填充“ l”(反转)

void FillList(struct ListNode* l, unsigned long long int result)
{
    struct ListNode *newNode = l;
    newNode->val = 0;
    while(result != 0)
    {
        newNode->val = result % 10;
        result /= 10;
        newNode->next = malloc(sizeof(struct ListNode));
        newNode = newNode->next;
    }
    newNode->next = NULL;
} 

输出是“ 7-> 0-> 8-> -1094795586”,而不是“ 7-> 0-> 8”。

3 个答案:

答案 0 :(得分:2)

假设我们创建的结果只是7

newNode->val = 0; // sets l to 0, OK so far
while(result != 0) // true!
{
    newNode->val = result % 10; // gets changed to 7
    newNode->next = malloc(sizeof(struct ListNode)); // you create a new node!
                                                     // (without assigning a value to it!)
    // now getting back to the while, discovering that you won't enter it again
    // but the next node is already created!
}

您需要避免此多余节点。一种可能的方式(对代码的最小更改):

struct ListNode* newNode = l;
for(;;)
{
    newNode->val = result % 10;
    result /= 10;
    if(result == 0)
        break;
    // at this point we now KNOW that we yet need another node, so we create it
    newNode->next = malloc(sizeof(struct ListNode));
    newNode = newNode->next;
}
newNode->next = NULL;

您会发现,l和{的第一个赋值(当newNode仍指向同一节点时)也涵盖了0的特殊情况。 {1}}仍为0 ...

答案 1 :(得分:1)

问题在于,即使没有下一个值,您也总是在分配新的下一个节点。

while(result != 0)
{
    newNode->val = result % 10;
    result /= 10;
    newNode->next = malloc(sizeof(struct ListNode));  // <<<<<<-----
    newNode = newNode->next;
}

这有点棘手,因为您希望在每次迭代中分配一个音符,但是您已经从分配的节点开始,使得第一次迭代成为一种特殊情况。

我们可以通过记住上一个节点是什么来解决此问题。

void FillList(struct ListNode* node, unsigned long long int num)
{
    struct ListNode* prev = NULL;
    do {
        // Since prev starts NULL this only happens the second time.
        if( prev ) {
            prev->next = node = malloc(sizeof(struct ListNode));
        }
        node->val = num % 10;

        // It's safer to always ensure everything is initialized.
        node->next = NULL;
        num /= 10;

        // Store the current node as the previous one.
        prev = node;
    } while(num != 0);
}

通过使用do / while循环,即使num从0开始,我们也确保它始终运行一次。在特殊情况下,这消除了0。

答案 2 :(得分:1)

在您的情况下,头节点l始终不等于NULL。 并假设您的头节点l为NULL并且您的代码可以为

void FillList(struct ListNode* l, unsigned long long int result){
    struct ListNode *newNode = NULL,*pNode=NULL;
    do{
      newNode=malloc(sizeof(struct ListNode));
      newNode->val = result % 10;
      newNode->next = NULL;
      if(l==NULL){
         l=newNode;
         p=newNode;
      }else{
         p->next=newNode;
      }
    }while((result /= 10)>0);
}