在列表中间插入一些东西的好方法是什么?

时间:2009-01-20 05:44:30

标签: c# list sorting insert

这可能是一个简单的问题。假设我有一个小型列表,大约有20-50个条目。类似的东西:

class Item
{
   int ItemNumber;
   int OrderNumber;
   string Name;
}

stored in something like
List<Item>

这存储在OrderNumber从1,2,3,4,...... 50开始的通用列表或数组中。为了简化操作,我们假设OrderNumber已经在其他地方通过QuickSort在List中排序(除非这会使事情变得更复杂)。

假设我想将Item.OrderNumber = 30移动到Item.OrderNumber = 20或类似的地方。当我这样做时,现在需要移动20以上的所有东西,以便旧的20现在是21,21现在是22等等,直到我达到30.它还需要反过来,所以当Item.OrderNumber = 30移动到Item.OrderNumber = 34,一切都必须向下移动。

我正在考虑将列表冒泡几次,但我希望有更好的方法来做到这一点。虽然列表大小很小,但这需要为各种不同的事情做很多事情。

编辑:只是为了让你知道。结果最终必须存储在某种类型的事务中的数据库中。

5 个答案:

答案 0 :(得分:2)

是否必须是List<T>?如果没有,您可以考虑使用SortedList<TKey, TValue>SortedDictionary<TKey, TValue>。然后,您可以使用OrderNumber作为键,只需让集合完成工作。

对于List<T>,您可以List<T>.BinarySearch使用IComparer<T>与适当的int position = list.BinarySearch(newOrder, orderComparer); list.Insert(position >= 0 ? position : ~position, newOrder); 进行比较,并按订单号进行比较 - 您可以:

IComparer<T>

您可以在整个代码中使用相同的{{1}}实例,因为它将是无状态的。

编辑:此解决方案不会更改Robert Wagner's answer中建议的任何其他条目的OrderNumber。

答案 1 :(得分:1)

如果我理解正确,你试图将OrderNumber保持在对象内(无论出于何种原因),但需要能够将新对象添加到列表中并使所有其他对象调整其OrderNumber以使新的一个合适。此外,列表中项目的实际顺序也不一定重要。

这可以通过包装列表并实现您自己的操作(移动/插入/删除功能,执行以下操作来完成):

插入 循环遍历所有项目并将ordernumber增加1,其中ordernumber> = new item的订单号 将项目添加到列表

删除 删除该项目 循环遍历所有项目并将ordernumber减少一个ordernumber&gt;已删除商品的订单号

<强>移动 删除该项目 重新编号该项目 插入项目

答案 2 :(得分:0)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Class1
{                     
    static void Main()
    {
        var beatles = new LinkedList<string>();

        beatles.AddFirst("John");                        
        LinkedListNode<string> nextBeatles = beatles.AddAfter(beatles.First, "Paul");
        nextBeatles = beatles.AddAfter(nextBeatles, "George");
        beatles.AddAfter(nextBeatles, "Ringo");


        LinkedListNode<string> paulsNode = beatles.NodeAt(1); // middle's index
        LinkedListNode<string> recentHindrance = beatles.AddBefore(paulsNode, "Yoko");
        recentHindrance = beatles.AddBefore(recentHindrance, "Aunt Mimi");
        beatles.AddBefore(recentHindrance, "Father Jim");


        Console.WriteLine("{0}", string.Join("\n", beatles.ToArray()));

        Console.ReadLine();                       
    }
}

public static class Helper
{
    public static LinkedListNode<T> NodeAt<T>(this LinkedList<T> l, int index)
    {
        LinkedListNode<T> x = l.First;

        while ((index--) > 0) x = x.Next;

        return x;
    }
}

答案 3 :(得分:0)

如果你使用双链表,你可以在19之后或20之前将OrderNumber = 30非常便宜地插入到该位置。然后迭代到小于30的OrderNumber并将每个订单增加1。反向移动列表中较高的项目。

答案 4 :(得分:0)

在填充列表后进行排序,然后通过粘贴到最后来填充。如果您需要随时进行分类,请按照Skeet的说法进行分类。