C 中链表的结构

发布于 2024-10-11 07:54:20 字数 217 浏览 4 评论 0原文

很抱歉问了这么愚蠢的问题,但我真的很困惑。

struct Amit
{
  int a;
  struct Amit *link;
}
*start;

这里*link*start都是用来指向链表的一个节点,但是这两个有什么区别,为什么我们不能把*start 在结构体内?

Sorry for asking such a stupid question but I am really confused.

struct Amit
{
  int a;
  struct Amit *link;
}
*start;

Here both *link and *start are used to point to a node of a linked list, but what's the difference between these two and why can't we put *start inside the structure body?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

尽揽少女心 2024-10-18 07:54:20

link 是结构类型的成员。每个 struct Amit 类型的结构都有一个。

start 是“指向struct Amit 的指针”类型的变量。在任何给定时间,最多可以有一个名为 start 的变量可见。

您可以将 start 放入结构中,但它将成为结构的成员(如 link),并且您仍然需要声明结构类型的变量,或者指向他们的指针。

这个想法是,列表中除最后一个之外的每个结构都包含一个指向列表中下一个结构的link指针。通常,列表中最后一个结构的 link 指针为 NULL (0)。向下搜索列表时,您会查看值,当您需要下一项时,您可以按照 link 找到它,当 link 为 NULL 时停止。

struct Amit *item = start;
while (item != NULL && item->a != value_wanted)
    item = item->link;

可以改为构建一个循环链表,它具有不同的停止标准。


查看注释,并解释更多一点...

创建列表的一种方法是:

struct Amit root = { 0, NULL };
struct Amit *start = &root;

变量 root 是一个用 root.a == 0 初始化的结构,并且root.link == NULL(或者等效地,root.link == 0)。指针变量start指向(存储)root的地址。给定一个新节点:

struct Amit next = { 1, NULL };

我们可以将其添加到 start 指向的列表的前面:

next.link = start;
start = &next;

创建列表的更合理的方法是动态分配节点,包括根节点。一致性至关重要,因为您必须释放动态分配的节点,并且动态分配某些节点而另一些则不动态分配会很混乱。 (我假设函数 void *emalloc(size_t nbytes);malloc() 的一个覆盖函数,它永远不会返回空指针 - 所以它会进行错误检查对我来说。)

// Create the empty list
start = emalloc(sizeof(*start));
start->a = 0;
start->link = NULL;

// Create a node
struct Amit *node = emalloc(sizeof(*node));
node->a = 42;
node->link = NULL:

// Add the node to the font of the list
node->link = start;
start = node;

您通常会将这些东西打包成管理节点分配、初始化和链接的函数。

struct Amit *add_node(struct Amit *start, int value)
{
    struct Amit *node = emalloc(sizeof(*node));
    node->a = value;
    node->link = start;
    return start;
}

start = add_node(start, 42);
start = add_node(start, 30);
start = add_node(start, 18);

for (node = start; node->link != 0; node = node->link)
    printf("Node: %d (%p)\n", node->a, node->link);

ETC。

The link is a member of the structure type. Every structure of type struct Amit has one.

The start is a variable of type 'pointer to struct Amit'. At any given time, there can be at most one variable called start visible.

You could put start inside the structure, but it would become a member of the structure (like link), and you would still need to declare variables of the structure type, or pointers to them.

The idea is that each structure on a list except the last contains a link pointer to the next structure on the list. Normally, the last structure on the list has a link pointer that is NULL (0). When searching down a list, you look at the values, and when you need the next item, you follow the link to it, stopping when the link is NULL.

struct Amit *item = start;
while (item != NULL && item->a != value_wanted)
    item = item->link;

It is possible to build a circular linked list instead, which has a different stop criterion.


Looking at the comments, and explaining a bit more...

One way to create a list is:

struct Amit root = { 0, NULL };
struct Amit *start = &root;

The variable root is a structure initialized with root.a == 0 and root.link == NULL (or, equivalently, root.link == 0). The pointer variable start points to (stores the address of) root. Given a new node:

struct Amit next = { 1, NULL };

we can add that to the front of the list which start points to:

next.link = start;
start = &next;

A more plausible way to create a list is by dynamically allocating nodes, including the root node. Consistency is crucial because you have to free the dynamically allocated nodes, and having some nodes dynamically allocated and others not is messy. (I'm assuming that function void *emalloc(size_t nbytes); is a cover function for malloc() that never returns a null pointer - so it does the error checking for me.)

// Create the empty list
start = emalloc(sizeof(*start));
start->a = 0;
start->link = NULL;

// Create a node
struct Amit *node = emalloc(sizeof(*node));
node->a = 42;
node->link = NULL:

// Add the node to the font of the list
node->link = start;
start = node;

You'd normally package this stuff up into functions which manage the allocation, initialization and linking of the nodes.

struct Amit *add_node(struct Amit *start, int value)
{
    struct Amit *node = emalloc(sizeof(*node));
    node->a = value;
    node->link = start;
    return start;
}

start = add_node(start, 42);
start = add_node(start, 30);
start = add_node(start, 18);

for (node = start; node->link != 0; node = node->link)
    printf("Node: %d (%p)\n", node->a, node->link);

Etc.

想你只要分分秒秒 2024-10-18 07:54:20

这基本上定义了三件事:

  • struct(顺便说一下,不要将其大写为 Struct)
  • 结构内的成员变量,名为 link
  • 结构外部的变量,名为start

您可以通过将结构体的定义与 start 变量的声明分开来减少混乱,如下所示:

struct Amit
{
  int a;
  struct Amit *link;
};

struct Amit *start;

This basically defines three things:

  • a struct (don't capitalize it as Struct, by the way)
  • a member variable within the struct, named link
  • a variable outside the struct named start

You can reduce the confusion by separating the definition of the struct from the declaration of the start variable, like this:

struct Amit
{
  int a;
  struct Amit *link;
};

struct Amit *start;
睡美人的小仙女 2024-10-18 07:54:20

如果您将“链接”重命名为“下一个”,可能会帮助您更好地理解它。链表就像一条链 - 您的“开始”(或通常称为列表“头”)是链的第一个环,链的下一个环通过您的“下一个”指针链接到它(在你的情况下,你的“链接”指针)。当没有其他环时(链接为 NULL),您知道您到达了链上的最后一个项目。

If you rename "link" to "next" it might help you get a better sense of it. A linked list is like a chain - your "start" (or as usually called, the list "head") is the first ring of the chain, and the next ring of the chain is linked to it through your "next" pointer (in your case, your "link" pointer). You know you got to the last item on your chain when there are no other rings (link is NULL).

演多会厌 2024-10-18 07:54:20

Start 指向列表顶部,并且可供您的程序全局使用。而链接仅跟踪下一个项目,并且在引用特定“节点”时可用。看看这张图,也许可以帮助你直观地理解!

link 在内部跟踪后续项目,该项目跟踪下一个组件的位置,因为它不一定像数组那样连续。

+------+     +------+     +------+
| data |     | data |     | data |
+------+     +------+     +------+
| link |---->| link |---->| link |----> NULL
+------+     +------+     +------+
   ^
   |
 START (Keep track of the whole list.)

希望这有助于澄清。

Start points to the top of the list and is available globally to your program. Whereas link just keeps track of the next item, and is available when referring to a specific 'node'. See this diagram it may help you understand with a visual!

link internally tracks the following item which keeps track of where the next component is as it is not necessarily contiguous the way arrays are.

+------+     +------+     +------+
| data |     | data |     | data |
+------+     +------+     +------+
| link |---->| link |---->| link |----> NULL
+------+     +------+     +------+
   ^
   |
 START (Keep track of the whole list.)

Hope that helps clarify.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文