我即将创建一个可以插入和显示的链接到现在为止:
struct Node {
int x;
Node *next;
};
这是我的初始化函数,只会为第一个 Node
调用:
void initNode(struct Node *head, int n){
head->x = n;
head->next = NULL;
}
要添加 Node
,我认为我的链表无法正常工作的原因在于此函数:
void addNode(struct Node *head, int n){
struct Node *NewNode = new Node;
NewNode-> x = n;
NewNode -> next = head;
head = NewNode;
}
我的 main
功能:
int _tmain(int argc, _TCHAR* argv[])
{
struct Node *head = new Node;
initNode(head, 5);
addNode(head, 10);
addNode(head, 20);
return 0;
}
让我按照我认为有效的方式运行该程序 . 首先,我将头部 Node
初始化为 Node
,如下所示:
head = [ 5 | NULL ]
然后我添加一个n = 10的新节点,并将head作为我的参数 .
NewNode = [x |下一步指向下一个点 . 然后我改变了head指向NewNode的位置,因为NewNode现在是LinkedList中的第一个Node .
为什么这不起作用?我会很感激任何可以让我朝着正确方向前进的提示 . 我认为LinkedList有点难以理解 .
当我打印这个时,它只返回5:
10 回答
我认为,为了确保列表中每个节点的非正式链接,
addNode
方法必须如下所示:这是我在这种情况下可以想到的最简单的例子,并没有经过测试 . 请考虑这使用了一些不好的做法,并且不会像往常那样使用C(初始化列表,声明和定义的分离等) . 但这是我在这里无法涵盖的主题 .
我强烈建议你阅读一些关于C和面向对象编程的内容 . 一个很好的起点可能是这样的:http://www.galileocomputing.de/1278?GPP=opoo
编辑:添加了弹出功能和一些输出 . 正如您所看到的,该程序将推送3个值5,10,20,然后弹出它们 . 之后订单相反,因为此列表在堆栈模式下工作(LIFO,后进先出)
你应该参考一个头指针 . 否则,指针修改在函数外部不可见 .
这两个功能都错了 . 首先,函数
initNode
有一个令人困惑的名字 . 它应该命名为例如initList
,不应该执行addNode的任务 . 也就是说,它不应该向列表中添加值 .事实上,函数initNode没有任何意义,因为列表的初始化可以在定义头时完成:
要么
因此,您可以从列表设计中排除函数
initNode
.同样在您的代码中,不需要为结构
Node
指定详细的类型名称,即在名称Node
之前指定关键字struct .函数
addNode
将改变head的原始值 . 在函数实现中,只更改作为参数传递给函数的头的副本 .该函数可能看起来像:
或者,如果您的编译器不支持初始化的新语法,那么您可以编写
或者不使用指向指针的指针,而是可以使用对Node指针的引用 . 例如,
或者您可以从函数返回更新的头:
并在
main
写道:addNode
函数需要能够更改head
. 现在只需更改局部变量head
(参数)即可 .将代码更改为
会解决这个问题,因为现在
head
参数是通过引用传递的,被调用的函数可以改变它 .我会加入战斗 . 自从我写完C以来已经太久了 . 此外,这里没有完整的例子 . OP的代码基本上是C,所以我继续使用GCC .
之前已经涵盖了这些问题;
next
指针未被提升 . 这就是问题的症结所在 .我也借此机会进行了建议编辑;而不是有两个函数
malloc
,我把它放在initNode()
然后使用initNode()
到malloc
两者(如果你愿意,malloc
是"the C new") . 我更改initNode()
以返回指针 .汇编:
gcc -o ll ll.c
输出:
以下是一个示例链接列表
head
在主要内部定义如下 .但是你只是改变了
addNode()
和initNode()
函数的头部 . 这些变化并没有反映在主要方面 .将头部的声明设为全局,不要将其传递给函数 .
功能应如下 .
使用:
在代码中有一个错误:
这是必要的: