【问题标题】:Moving items in linked list C#.NET在链表 C#.NET 中移动项目
【发布时间】:2009-07-29 21:48:18
【问题描述】:

我正在尝试移动列表中的项目,但是当我与最后一个选项进行比较时,我在移动移动链接列表中的项目之前退出了。有没有办法在节点被放在最后并且无法循环移动项目之前做到这一点?

LinkedList<BD> list = new LinkedList<BD>(b[arg].Values);   
LinkedListNode<BD> node, terminator, next = null;
List<LinkedListNode<BD>> move = new List<LinkedListNode<BD>>();

terminator = list.First;
node = next = list.Last;

while (next != null && next != terminator)
{
    node = next;
    next = next.Previous;
    if (IDs.Contains(node.Value.Id))
    {
        move.Add(node);
        list.Remove(node);
    }
    else
    {
        foreach (var item in move)
        {
            list.AddBefore(node, item);
            node = node.Previous;
        }
        move.Clear();
    }
}

【问题讨论】:

  • 请编辑您的问题,选择代码部分,然后按编辑器上方的小“代码”按钮。这使得代码更容易阅读。
  • @Bruce227:您能否描述一下您要完成的工作?是否要分析节点,检查节点的 DocumentVersionId 是否在 IDs 列表中,然后将该节点移动到链表的最前面?
  • 我想将“移动”中的节点移动到链表中的不同位置。唯一的问题是如果我将它移到列表的前面。在这种情况下,它不会执行 foreach 将项目放回列表中。

标签: c# linked-list


【解决方案1】:

这对我有用。我尝试了不同的方法并想寻求帮助,但这对我有用的不仅仅是移动到前面,而且只是移动到列表中:

while (next != null)
{
   node = next;
   next = next.Previous;

   if (IDs.Contains(Id))
   {
      move.Add(node);
      list.Remove(node);
   }
   else
   {
      foreach (var item in move)
      {
         list.AddBefore(node, item);
         node = node.Previous;
      }
      move.Clear(); 
   }

   if (next == null) 
   {
      foreach (var item in move)
      {
         list.AddFirst(item);
      }
      move.Clear();
   }
}

【讨论】:

    【解决方案2】:

    您的代码将两个列表交错 - 这对我来说看起来不正确。
    我认为,而不是重复的块

    foreach (var item in move)
    {
        list.AddBefore(node, item);
        node = node.Previous;
    }
    move.Clear();
    

    你可能想要类似的东西

        var before = node.Previous;
        var LinkedListNode<BD> current = null;
        foreach (var item in move)
        {
            list.AddBefore(node, item);
            current = node = item;
        }
        current.Previous = before; // assumes move was not empty
        move.Clear();
    

    跟踪您插入的位置。

    【讨论】:

    • 很抱歉,我删除了移动的第一个 foreach,但它又被添加了回来。我试图调用它是否要结束循环并移动项目。我会试一试,看看它是否有效。谢谢
    • 这行不通,因为它没有使用当前代码到达该部分并且没有被调用。问题是 next 为空,因为它位于列表的开头。因此,即使我确实调用了 foreach 节点,也不会再使用 .previous
    • 1) 我的重构毫无意义,因为它只是在猜测 LinkedList 正在为您做什么(我猜对手动“C”的记忆太多了)2)而不是 while,使用do {} while (node != list.First); 会在循环中提供额外的转折。或者,通过无条件的 foreach/addFirst 跟随循环。
    【解决方案3】:

    这样的? (我试图基于你的代码):

    LinkedList<BD> list = new LinkedList<BD>(b[arg].Values);
    LinkedListNode<BD> node = list.Last;
    LinkedListNode<BD> terminator = null;
    
    while (node != null && node != terminator) {
        if (IDs.Contains(node.Value.DocumentVersionId)) {
            LinkedListNode<BD> tempNode = node;
            node = node.Previous;
    
            list.Remove(tempNode);
            list.AddFirst(tempNode);
            if (terminator == null) terminator = tempNode;
        } else {
            node = node.Previous;
        }
    }
    

    这段代码应该将你的“DocumentVersionId-matched”节点移动到链表的前面。

    下面是一个简单的整数示例来演示它是如何工作的:

    List<int> specials = new List<int> { 1, 4, 5, 7 };
    List<int> source = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8 };
    LinkedList<int> list = new LinkedList<int>(source);
    
    LinkedListNode<int> node = list.Last;
    LinkedListNode<int> terminator = null;
    
    while (node != null && node != terminator) {
        if (specials.Contains(node.Value)) {
            LinkedListNode<int> tempNode = node;
            node = node.Previous;
    
            list.Remove(tempNode);
            list.AddFirst(tempNode);
            if (terminator == null) terminator = tempNode;
        } else {
            node = node.Previous;
        }
    }
    

    结果链表将包含:
    1, 4, 5, 7(链表开头的特价), 2, 3, 6, 8

    无限循环应该是不可能的。

    回答修改:
    - node = list.Firstnode = list.Last
    - 添加了一个整数示例

    【讨论】:

    • 这些项目在列表中向上移动。只是如果我要先移动,就会出现问题。我会试试你的代码。谢谢
    • @Bruce227:我添加了一个简单的整数示例来展示我的答案中的代码是如何工作的
    • 出于某种原因,当我使用该代码时,我不只是想将项目移到前面。如果向上移动列表,当它到达第一个它丢失时,我遇到了问题。我认为将多个间隔移动也存在问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多