为此问题选择正确的数据结构:循环链表,列表,数组或其他内容

时间:2009-06-22 17:34:42

标签: c# .net performance data-structures

我的要求是每种类型T,我有许多元素(在1-30 +之间),首先我需要随机项目,然后我需要下一个,当我到达最后一个项目时,它应该返回第一个,依此类推。

所以说T是Icon,而集合是Images(实例)。

我希望:

// program start:

Icon icon = RandomIcon(); // say 5th one for this case

// user clicks next icon:

icon = current++; (6, 7, 8, 1, 2, ...)

对我来说,圆形链表是有意义的,除了我必须做O(n),其中n是随机索引。

我想拥有最干净,最好的实施,因此问题。

4 个答案:

答案 0 :(得分:5)

另一种可能的解决方案是创建一个链接列表,其底层数据结构是一个数组。这样你就可以在O(1)处索引,同时保持你的“圆度”

public class myLL
{
    private T[] items;
    private int i;
    private int max_size;

    public T GetCurrent() {
        return items[i];
    }

    public T GetNext() {
        i = i++ % max_size;
        return items[i];
    }
}

答案 1 :(得分:2)

我会考虑使用包含数组或List< T>的自定义类。在内部,并创建一个从任何索引开始的自定义枚举器,并枚举循环。

我认为这比LinkedList更好的主要原因与此行有关:

Icon icon = RandomIcon(); // say 5th one for this case

从索引集合中获取随机项比链接列表更容易和更高效....并且使用30个元素,在任何一种情况下枚举都会很快。

要处理循环中的迭代,您只需要这样:

class CircularlyEnumerableList<T>
{
    private List<T> list;

    // Implement whatever you need for list...

    IEnumerable<T> EnumerateFromElement(int index)
    {
        for (int i=index; i<list.Count; ++i)
             yield return list[i];

        for (int i=0; i<index; ++i)
             yield return list[i];
    }
}

答案 2 :(得分:1)

  • 圆形清单很好
  • 由于你有大约30个元素(而不是像3000一样),你可以考虑索引表而不是链表
    • 如果您的元素不会被添加和删除,这将立即生效
  • 如果您有动态插入和删除的元素,您仍然可以编写一些代码来处理(coz,小列表)
  • 如果所有这些对你有用,剩下的就是1-N之间的随机。

  • 如果每个列表的项目数很少,那么实施一个列表
  • 将是一个过度杀戮
  • 但是,如果您选择这样做,您仍然可以在列表中首次遍历随机选择的起点

答案 3 :(得分:1)

为什么要使用链接列表?使用数组并存储当前项的索引。调用函数以获取下一个项目时,请递增索引。如果索引大于元素数,请将索引设置为零。