我有一个如下构造的链表:
LinkedList<int> linked = new LinkedList<int>();
var array = new int[] { 23, 55, 64, 65 };
foreach (var item in array)
{
linked.AddLast(item);
}
如何找到数字64的索引?
答案 0 :(得分:12)
唯一的方法是逐个元素检查并增加一个计数器(通过“only way”,我说其他方法如LINQ需要在内部做同样的事情。)
手写的扩展方法看起来像这样:
public static class LinkedListExt
{
public static int IndexOf<T>(this LinkedList<T> list, T item)
{
var count = 0;
for (var node = list.First; node != null; node = node.Next, count++)
{
if (item.Equals(node.Value))
return count;
}
return -1;
}
}
但是可以使用LINQ作为@L.B wrote轻松完成(产生相同的时间复杂度)。
答案 1 :(得分:2)
int index = linked.Select((item, inx) => new { item, inx })
.First(x=> x.item == 64).inx;
答案 2 :(得分:2)
这是一个备用的LINQ实现,可以避免创建匿名对象,如果项目不在列表中,则返回-1:
int index = linked.Select((n, i) => n == 64 ? (int?)i : null).
FirstOrDefault(n => n != null) ?? -1;
它将数字序列转换为包含匹配索引的序列,否则转换为null
。如果有一个,则需要第一个,否则将默认int?
转换为-1
。
修改强>
这是一个更好(更简单,更高效)的选择:
int i = linked.TakeWhile(n => n != 64).Count();
i
将等于索引,如果找不到值linked.Count
,则等于64
。
答案 3 :(得分:1)
我认为您应该创建自己的函数来解析列表并进行检查。 “查找”功能仅返回第一次出现,对于您,可能在列表中出现2次或多次64次。
答案 4 :(得分:0)
您可以补个。 :)我发现了这个问题,试图找出如何对链表进行qsort。这让我很吃惊,因为我无论如何都要对结构进行排序,我所要做的就是为每个结构赋予唯一的标识符。这可能是创建它们的顺序。只需向每个节点添加一个称为seq或idx的int字段即可。将您的int更改为带有内部int的结构,并附加另一个int字段即即兴索引。遍历列表将很麻烦。但是您将原始整数绑定到索引。
如果您不希望数据四处移动,则可以构建一个指向链接列表元素的指针数组。从头开始,使用指向下一个的指针,继续这样做并计算跳数。然后分配数组,再次从列表的开头开始,并在数组中记录下一个指针的地址。但是某人或某物(另一个线程?)可以通过移动或添加或删除元素来将其拧紧。该列表将继续起作用,但是需要废弃并重做阵列。可能比较快,但是如何可靠地检测到变化?
圆形?只需使用模,以便向前移动idx =(idx + 1)%N,其中N是字段的总数。无论如何,对于普通的C,我不知道C#的局限性。