简体   繁体   English

C中的链表结构

[英]Structure In C for linked list

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? 这里*link*start都用来指向链表的一个节点,但是这两者之间有什么区别,为什么我们不能将*start放在结构体中?

The link is a member of the structure type. link是结构类型的成员。 Every structure of type struct Amit has one. struct Amit类型的每个结构都有一个。

The start is a variable of type 'pointer to struct Amit '. start是类型为“指向struct Amit的指针”的变量。 At any given time, there can be at most one variable called start visible. 在任何给定时间,最多只能有一个变量称为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. 您可以将start放在结构内部,但是它将成为结构的成员(如link ),并且仍然需要声明结构类型的变量或指向它们的指针。

The idea is that each structure on a list except the last contains a link pointer to the next structure on the list. 想法是,列表中除最后一个结构外的每个结构都包含指向列表中下一个结构的link指针。 Normally, the last structure on the list has a link pointer that is NULL (0). 通常,列表上的最后一个结构的link指针为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. 向下搜索列表时,将查看值,当需要下一项时,将跟随该link ,在link为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 ). 变量root是使用root.a == 0root.link == NULL初始化的结构(或等效地, root.link == 0 )。 The pointer variable start points to (stores the address of) root . 指针变量start指向root (存储其地址)。 Given a new node: 给定一个新节点:

struct Amit next = { 1, NULL };

we can add that to the front of the list which start points to: 我们可以将其添加到列表的startstart指向:

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.) (我假设函数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;

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. 等等。

This basically defines three things: 这基本上定义了三件事:

  • a struct (don't capitalize it as Struct, by the way) struct (顺便说一下,不要将其大写为Struct)
  • a member variable within the struct, named link 结构中的成员变量,名为link
  • a variable outside the struct named start 名为start的结构外部的变量

You can reduce the confusion by separating the definition of the struct from the declaration of the start variable, like this: 您可以通过将struct的定义与start变量的声明分开来减少混乱,如下所示:

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

struct Amit *start;

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. 希望有助于澄清。

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). 链接列表就像一条链-您的“开始”(或通常称为列表“ head”)是链的第一个环,而链的下一个环通过“下一个”指针(在您的情况下,您的“链接”指针)。 You know you got to the last item on your chain when there are no other rings (link is NULL). 您知道当没有其他环(链接为NULL)时,您到达链上的最后一个项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM