2

我一直致力于在 C 中实现链表。所以在有人对我大喊大叫之前:是的,这是“家庭作业”。我一直在尝试解决和研究 Nick Parlante 的“链表基础知识”——可在以下网址免费获得:http: //cslibrary.stanford.edu/103

功能:在链表末尾插入元素

我偶然发现了一个实现问题并设法构建了一个解决方法:如果我在 LList 中使用“EndPointer”,我可以使用返回函数来设置函数的 EndPointer 以移交新的 ReferencePointer,然后在 main.xml 中更改它。

代码 - 工作正常,但解决方法:

// within main
lastPtrRef = _pushEnd(lastPtrRef, i);

// == function: push to end
node** _pushEnd(node **endRef, int value)
{
    // 1) allocate stack mem / make room for new element
    node *newNode = malloc(sizeof(node));

    // do the data work
    newNode->value = value;

    // 2) make  element point to NULL (fo beeing the new last element
    newNode->next = NULL;

    // 3) make old last element point to new element
    *endRef = newNode;

    return &(newNode->next); // more readable then vers. below
    // this returns the mem address only of the pointer of the node!!!
    //return (&((*endRef)->next));

}

==================================================== ==============================

到目前为止,这就是我在函数中所做的所有工作,但它实际上不起作用。关于我没有得到哪一点的任何提示?!

void _pushEnd(node **endRef, int value)
{
// 1) allocate stack mem / make room for new element
node *newNode = malloc(sizeof(node));

// do the data work
newNode->value = value;

// 2) make  element point to NULL (fo beeing the new last element
newNode->next = NULL;

// 3) make old last element point to new element
*endRef = newNode;

}

难道是,我实际上需要一个指向引用指针的指针来实际更改指向最后一个元素的指针的内容(在范围内:main),所以我目前似乎只是在修改局部变量“endRef”和不是它的内容?!

任何帮助,将不胜感激...


编辑:这个想法是在 LList 的开头不使用虚拟节点来追加。

我的结构如下所示:

typedef struct node     {
int     value;
struct node *next;      } node;

主要 - 局部变量(堆栈):

node *head = NULL;
node **lastPtrRef = &head;

编辑:无论如何,大多数命题最终都返回了 refPointer。但也许这不是一个坏主意,因为它不需要另一个指向 refPointer 的 refPointer。

感谢您的所有帮助和许多有用的评论!

4

4 回答 4

3
*endRef = newNode;

在您这样做之前,您必须说明endRef->nextnewNode.

if (*endRef)
    (*endRef)->next = newNode;

*endRef = newNode;
于 2013-02-23T11:42:02.700 回答
3

_pushEnd告诉main我们main已经知道的:指针的存储位置。

您有很多选择,包括:

  • pushEnd 获取 node*(不是 node**),返回新的指针并将它的 main 存储在它的变量中

  • pushEnd 获取 node** 并自行覆盖 main 的值,无需返回任何内容。

编辑:

第 1 点的示例:

node* pushEnd(node* end, int entry); // returns new end.
int main() {
    node* end = newlist();
    int i=0;for(;i<10;++i) {
        end = pushEnd(end, i);
    }
}

第 2 点的示例:

void pushEnd(node** ptrToEnd, int entry); // changes *ptrToEnd
int main() {
    node* end = newlist();
    int i=0;for(;i<10;++i) {
        pushEnd(&end, i);
    }
}
于 2013-02-23T11:43:12.697 回答
1

我认为您的问题在于退货线:

return (&((*endRef)->next));

正如您在此之前所做的那样,*endRef = newNode;它现在返回您刚刚创建的节点的下一个元素的方向。

于 2013-02-23T11:42:27.617 回答
1
struct node {
   struct node *next;
   int value;
   };

struct node *root = NULL
   , **lastPtrRef = &root;

 // within main
lastPtrRef = pushEnd(lastPtrRef, i);

//function: push to end; return new pointer to tail->next

struct node  **pushEnd(struct node **p, int value)
{
    struct node *p;

    // 0) is it really the end ?    
    while (*pp) {pp = &(*pp)->next; }

    // 1) allocate
    p = malloc(sizeof *p);

    // do the data work
    p->value = value;

    // 2) make  element point to NULL (fo beeing the new last element
    p->next = NULL;

    // 3) make old last element point to new element
    *pp = p;

    return &p->next;

}

或者删除 p 变量,因为它不需要:

struct node  **pushEnd(struct node **p, int value)
{

    while (*pp) {pp = &(*pp)->next; }

    *pp = malloc(sizeof **pp);
    (*pp)->value = value;
    (*pp)->next = NULL;

    return &(*pp)->next;

}
于 2013-02-23T13:28:16.437 回答