在链接列表中避免额外的Malloc(node-> next = NULL)

时间:2013-10-06 22:07:16

标签: c linked-list malloc

在我的链表中,我试图避免malloc额外节点而不添加一堆if语句等。我有以下内容:

polynomial create()
{
    polynomial head = NULL;
    polynomial temp = NULL;
    int numTerms, coefficient, exponent;
    int counter = 0;

    printf("Enter the number of terms in the polynomial: ");
    scanf ("%d", &numTerms);
    printf("\n");

    if (numTerms == 0) {
        head = malloc(sizeof(term));
        head->coef = 0; head->exp = 0; head->next = NULL;
        return head;
    }
    while (numTerms != counter) {
        // Ask for input
        printf("Enter the coefficient and exponent of term %d: ", (counter + 1));
        scanf("%d %d", &coefficient, &exponent);
        printf("\n");

        // Create the term
        if (temp == NULL) temp = malloc(sizeof(term));
        temp->coef = coefficient; temp->exp = exponent; temp->next = NULL;
        //if((numTerms - 1) != counter) temp->next = malloc(sizeof(term)); -- this is my workaround
        printf("Created: %d %d\n", temp->coef, temp->exp);

        // If this is the first node created, mark the head
        if (counter == 0) head = temp;
        // Increment the list and counter
        temp = temp->next;
        counter ++;
    }
    return head;
}

但是当我去打印多项式时(我有一个完美的功能),我得到以下内容:

Polynomial 1: 3x^4 - >在这种情况下,对head-> next的引用是NULL

所以我尝试了以下解决方法 - 只为新节点预先分配内存,但前提是这是用户输入的最后一次迭代。这是通过以下方式实现的:

替换temp->next = NULL;

if((numTerms - 1) != counter) temp->next = malloc(sizeof(term));

numTerms - 1阻止添加'额外节点',而malloc将保持对temp-> next的引用。如果我不使用if检查并且总是分配额外的内存,我最终会得到以下结果:

Polynomial 1: 3x^4 - 7x^2 + 5 + 10621224x^10617028

我错过了哪一部分分配会导致引用temp->接下来丢失?对于指针和内存管理,我真的非常糟糕,所以这可能是一个可怕的问题。

2 个答案:

答案 0 :(得分:4)

你做得比实际需要的要困难得多。考虑符合以下内容的链表的简单节点群:

  • 假设NULL表示空列表
  • 分配头指针,而不必为每次分配测试它。
  • 一个,每个节点只需要一个分配。
  • 节点以条目顺序显示在列表中。列表中的第一个节点是您输入的第一个节点,第二个节点是您输入的第二个节点,等等。

有了这个,请参阅下面的一般算法以及它如何适应您的代码:

struct node
{
    // your fields here
    struct node *next;
};

struct node* populate_list()
{
    struct node *head = NULL;
    struct node **pp = &head;
    int i=0, count=0;

    // TODO: set count: get your insertion limit here. 

    // now run the insertion loop
    for (i=0; i<count; ++i)
    {
        struct node *p = malloc(sizeof(*p));

        // TODO: initialize your node members here

        // save to our current tail-pointer, which is initially
        //  also the head pointer. then advance to the new tail
        //  pointer and continue the loop
        *pp = p;
        pp = &p->next;
    }

    // terminate the list.
    *pp = NULL;

    // and return the head pointer.
    return head;
}

注意:p只是为了清晰起见。您可以轻松地将该循环体减少到以下,这是完全有效的:

    // now run the insertion loop
    for (i=0; i<count; ++i)
    {
        *pp = malloc(sizeof(**pp));

        // TODO: initialize your node members here
        //  using (*pp)->member for access

        // save next pointer and continue.    
        pp = &(*pp)->next;
    }

调整您的代码

现在您知道如何执行此操作,它会大大减少您的代码:

polynomial create()
{
    polynomial head = NULL;
    polynomial *pp = &head;

    int numTerms, coefficient, exponent;
    int counter = 0;

    // prompt for valid number of terms.
    printf("Enter the number of terms in the polynomial: ");
    scanf ("%d", &numTerms);

    while (numTerms != counter)
    {
        // Ask for input
        printf("Enter the coefficient and exponent of term %d: ", (counter + 1));
        if (scanf("%d %d", &coefficient, &exponent) == 2)
        {
            *pp = malloc(sizeof(**pp));
            (*pp)->coef = coefficient;
            (*pp)->exp = exponent;
            pp = &(*pp)->next;
            ++counter;
        }
        else
        {   // eat the line and try again.
            scanf("%*[^\n]\n")
        }
    }
    *pp = NULL;

    return head;
}

答案 1 :(得分:0)

此外,您将发现存储中间表达式(如上所述)对二叉树的效果要好得多。您使用操作(+, - ,*,/,^)表示树的节点,并且还有一个括号树(其下的所有内容都是一个表达式,用括号括起来。

当您浏览表达式时,您将构建一个树,您会发现它可以递归执行。

使用深度优先,左节点右遍历完成打印树。