【问题标题】:Moving an item to the end of a double linked list in C [closed]在C中将项目移动到双链表的末尾[关闭]
【发布时间】:2020-10-24 12:03:20
【问题描述】:

我想创建一个函数,将双向链表中的项目移动到其列表的末尾。如果您想拥有一个结构列表,则该结构需要在其中包含一个 list_elem。在这里。

    struct list_elem 
  {
    struct list_elem *prev;     /* Previous list element. */
    struct list_elem *next;     /* Next list element. */
  };

在列表中也有头部和尾部。在提供的代码中,有一个 swap() 函数接受两个指向 list_elem 指针的指针,但我对如何使用它来移动列表中的项目有点困惑。这是。

static void
swap (struct list_elem **a, struct list_elem **b) 
{
  struct list_elem *t = *a;
  *a = *b;
  *b = t;
}

如果我有一个像 h -- 1 -- 2 -- 3 -- t 这样的列表,其中 h 是它的头部,t 是它的尾部,我想做一个函数,你可以给 struct list *l 和 list_elem *e 并将它转换成这个 (这个例子我会移动 1) h -- 2 -- 3 -- 1 -- t

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 如果我有一个像 h -- 1 -- 2 -- 3 -- t 这样的列表,其中 h 是它的头部,t 是它的尾部,我想做一个函数,你可以给 struct list *l 和 list_elem *e 和把它转换成这个(这个例子我将移动1)h -- 2 -- 3 -- 1 -- t
  • 只要不断交换元素与其后继元素,直到它是最后一个元素。一个更有效的解决方案是简单地删除元素并将其插入到列表的末尾。
  • 那个swap函数会导致next/prev指针不匹配的节点。

标签: c pointers doubly-linked-list


【解决方案1】:

至少有两种通用方法可以实现移动到末端操作:

  1. 从列表中删除目标节点,然后将其附加到末尾;或

  2. 在一个循环中,只要目标节点不是最后一个,就和它的后继节点交换。

实现其中任何一种的常用方法将涉及操作节点的prevnext 指针,但请注意问题中提供的swap() 函数不执行节点 交换,而是指针 交换。您可以通过提供的(指针)swap() 函数来实现选项 (2) 中描述的节点交换,但与直接使用所涉及的指针相比,它会更丑陋、更混乱且更容易出错。 (您的swap() 更适合用于指针数组而不是链表。)

其他细节留作应有的练习。

【讨论】:

  • O(n)(最坏情况)交换循环的用例是什么,当恒定时间 O(2) 删除-插入方法可用时(以及更容易编码) ...?
  • @Myst,如果您最初没有指向尾部的指针,则删除/插入也是 O(n)。或者可以设计一个示例,其中交换是唯一可以执行的操作,尽管这种情况在现实世界中不太可能出现。
  • 没错,swap 在我们有一个 singly 链表而没有已知的 tail 指针的情况下是一种有效的方法。然而,OP 询问了一个双重链表。如果没有指向头/尾的指针,则交换功能将在该指针上无限循环...
  • @Myst,双重链接循环不同。这两个特征是完全正交的。您绝对可以拥有一个双向链接的非循环链表并高效地工作,在该链表中您知道头部但不知道尾部。
  • 猜猜我学到了一些新东西。我从来没有使用过非循环双向链表的用例,所以我没有意识到它们可以在不将尾部链接到头部的情况下使用。感谢您的澄清??
猜你喜欢
  • 1970-01-01
  • 2012-11-02
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
  • 2014-05-19
  • 2020-04-07
  • 2020-06-09
  • 2020-04-13
相关资源
最近更新 更多