什么是插入列表中间的东西的好方法?
这可能是一个简单的问题。假设我有一个大约20-50个条目左右的小列表。例如:什么是插入列表中间的东西的好方法?
class Item
{
int ItemNumber;
int OrderNumber;
string Name;
}
stored in something like
List<Item>
它存储在通用列表或数组中,其中OrderNumber从1,2,3,4,... 50开始。为了使事情更容易,让我们假设OrderNumber已经在其他地方的QuickSort列表中排序(除非这使事情更加复杂)。
比方说,我想将Item.OrderNumber = 30移动到Item.OrderNumber = 20或类似的地方。当我这样做的时候,现在需要改变20以上的所有东西,以便旧的20现在是21,21现在是22等,直到我将它设置为30.它还需要以另一种方式进行,所以当Item.OrderNumber = 30移至Item.OrderNumber = 34,所有内容都必须向下移动。
我在考虑冒泡列表几次,但我希望有更好的方法来做到这一点。虽然列表大小很小,但对于各种不同的事情,这需要做很多工作。
编辑:只是让你知道。结果最终必须存储在数据库中,在某些类型的事务中。
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;
}
}
如果使用双链表,可以做ORDERNUMBER = 30的非常廉价的插入位置19后或20之前接着迭代,以小于30 ORDERNUMBER和通过增加各顺序1.在列表中移动一个更高的项目。
是否必须是List<T>
?如果不是,您可以考虑使用SortedList<TKey, TValue>
或SortedDictionary<TKey, TValue>
。然后,您可以使用OrderNumber作为关键字,并让集合完成工作。
Alterantively,为List<T>
可以使用List<T>.BinarySearch
用适当IComparer<T>
它通过订单号进行比较 - 你必须:
int position = list.BinarySearch(newOrder, orderComparer);
list.Insert(position >= 0 ? position : ~position, newOrder);
您可以使用相同的IComparer<T>
实例整个代码,因为这将是无状态。
编辑:此解决方案不会更改任何其他条目的OrderNumber,如Robert Wagner's answer中所建议的。
只需在填充列表后进行排序,然后通过在最后粘贴东西来填充。如果您需要随时分类,请执行Skeet所说的事情。
如果我理解正确,您试图将OrderNumber保留在对象内(无论出于何种原因),但需要能够将新对象添加到列表并使所有其他对象调整其OrderNumber以使新的适合。此外,列表中项目的实际顺序不(必然)重要。
这可以通过包装清单,并实现自己的操作(移动/插入/删除功能,做了以下来完成:通过所有的项目
插入 环和一个地方增加订单号码该订单号码> =新项目的订单号 的项目添加到列表中
删除 通过所有的项目中删除项目 环路和1减少订单号码,其中订单号码>已删除项目的订单号
移动 删除项目 重新编号项 插入项目
是List .BinarySearch到跳跃列表IMPL的接口? –
mabbit
2009-01-20 07:01:52
这仅仅是一个由数组支持的列表上的普通二分查找。 – 2009-01-20 07:08:58