【问题标题】:Understanding code in c (linked lists)理解 c 中的代码(链表)
【发布时间】:2017-04-11 11:54:43
【问题描述】:

我在理解链表时遇到了很大的问题,如果有人能解释我以下内容,我将不胜感激。

Element_t *pushfront(Element_t *list)
{ 
if(list==0)
return allocate();

list->prev=allocate();

list->prev->next=list;

list=list->prev;

return list;
}

这里的list->prev->next=list是什么意思?

这是什么意思:f->next->prev=f->prev

我知道这只是程序代码的一部分,但我希望有人能尽可能简单地给我这些的一般含义吗?

【问题讨论】:

标签: c pointers linked-list doubly-linked-list


【解决方案1】:

列表中的节点引用了列表中的前一个节点和下一个节点。

函数获取列表的第一个节点。所以这个第一个节点没有前一个节点。

在此声明中

list->prev=allocate();

创建了前一个节点,因为它从函数名开始,它将一个新节点推到列表的开头。

在此声明中

list->prev->next=list;

表达式list->prev 产生新创建节点的地址。此创建的节点应指向列表的当前第一个节点。因此它的数据成员next应该包含节点list的地址。

还有这句话

list->prev->next=list;

这样做。

如果引入一个中间变量可以想象的更简单。

例如

Element_t *new_node = allocate();

list->prev = new_node;      // list->prev=allocate();
new_node->next = list;     //list->prev->next=list;
list = new_node;           //list=list->prev;

return list;

至于这个问题

这是什么意思:f->next->prev=f->prev?

然后看起来节点f 已从列表中删除。现在它的下一个节点(f->next)不会指向f,而是指向f的前一个节点。

再一次,如果引入中间变量会更清楚。

Element_t *previous_node_of_f = f->prev;
Element_t *next_node_of_f = f->next;

next_node_of_f->prev = previous_node_of_f;  // f->next->prev=f->prev

如果还要添加这样的语句

previous_node_of_f->next = next_node_of_f;

然后节点 f 将从列表中完全删除。

       --------------------------------------------------------
       |                                              prev    ^
       |                                                      |
----------------------    ----------------------    ----------------------
| previous_node_of_f |    |         f          |    |    next_node_of_f  |    
----------------------    ----------------------    ----------------------
       |                                                     ^  
       |    next                                             | 
       -------------------------------------------------------

【讨论】:

    【解决方案2】:

    Element_t 可能是typedef,类似于以下内容:

    typedef struct Element {
        struct Element * next;
        struct Element * prev;
        void * data;
    } Element_t;
    

    假设这个,你的链表基本上是这样工作的:

                      (list)
                         A               B               C
                    +----------+    +----------+    +----------+
                    | next=B   |--->| next=C   |--->| next=0   |
                    | prev=0   |<---| prev=A   |<---| prev=B   |
                    | data="A" |    | data="B" |    | data="C" |
                    +----------+    +----------+    +----------+
    

    所以现在你想在A前面添加一个新节点N

                      (list)
         N               A               B               C
    +----------+    +----------+    +----------+    +----------+
    | next=A   |--->| next=B   |--->| next=C   |--->| next=0   |
    | prev=0   |<---| prev=N   |<---| prev=A   |<---| prev=B   |
    | data="N" |    | data="A" |    | data="B" |    | data="C" |
    +----------+    +----------+    +----------+    +----------+
    

    所以,1. A->prev 需要设置为 N 和 2. N->next 需要设置为 A.

    list-&gt;prev=allocate(); 这分配了新的 N 并且已经分配了 A->prev=N。

    下一行:list-&gt;prev-&gt;next=list:将list-&gt;prev 读取为刚刚分配的新节点。然后是 N->next=A - 第二步。

    并且您的新元素已链接到列表中。显然allocate()需要将nextprev初始化为NULL

    这是什么意思:f->next->prev=f->prev?

    取决于它的写入位置。在这里,它可能是函数的一部分,从列表中删除一个节点。

    【讨论】:

      【解决方案3】:

      首先,链表通过指针相互链接。它们不是按顺序排列的,实际上它们是分布在内存中的。

      让我回答你的问题-1 list-&gt;prev-&gt;next=list; 在这里,您将前一个节点与当前节点链接起来。此代码表示将下一个或上一个链接到当前节点。然后前一个节点现在与结构中定义的下一个指针链接。 获取问题2f-&gt;next-&gt;prev=f-&gt;prev; 我不知道这是在哪里定义的,但在这里你正在做一个带圆圈的链表。通过此代码链接到第一个节点的最后一个节点。

      【讨论】:

        【解决方案4】:

        这是你的 cmets 代码,它告诉你发生了什么。

        Element_t *pushfront(Element_t *list)
        { 
        if(list==0) // If the list is emtpy
        return allocate(); /* then you simply create a new node, which 
        represents your list and return it. The size of your list grew from 0 to 1.*/
        
        list->prev=allocate(); /*If the list is not empty, you add a new node by creating it,
        and then the prev pointer of the first element in the list (list->prev) 
        is set to this new element, as you want it to be first.*/
        
        list->prev->next=list; /*Then you need to set the next pointer 
        to the element you just added. The new element is at list->prev, 
        so by list->prev->next, you just say, that the next element of the one
         you just created is the element that was first before you added the new one*/
        
        list=list->prev; /* Here you just set the new element as the head of the list*/
        
        return list; /*And here you return the new list*/
        }
        

        请注意,您的列表总是作为指向第一个元素的指针传递,因为这就是您所需要的。然后,您可以通过为列表中的每个元素设置的next 指针访问所有元素。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-07-24
          • 2015-02-24
          • 2017-03-23
          • 1970-01-01
          • 2011-04-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-02
          相关资源
          最近更新 更多