Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 列表中使用哪种算法<;T>;动态分配内存?_C#_.net_Arrays_Algorithm_Data Structures - Fatal编程技术网

C# 列表中使用哪种算法<;T>;动态分配内存?

C# 列表中使用哪种算法<;T>;动态分配内存?,c#,.net,arrays,algorithm,data-structures,C#,.net,Arrays,Algorithm,Data Structures,现在我有了一个在阵列上动态分配内存的算法: 如果数组已满,我将创建一个两倍大小的新数组,并复制项 如果数组已满四分之一,我将创建一个大小为一半的新数组,并复制项 这是一个相当快速的动态内存分配算法,尽管将元素复制到新分配的数组会有额外的开销 什么是更快的,List或基于数组的算法?你建议用什么 List是否使用简单数组作为内部数据结构 List在内部使用数组,它使用与您类似的策略-如果长度超过数组的长度,它将使数组的大小加倍。然而,如果尺寸小得多,它不会使它变小 mscorlib中的相关方法

现在我有了一个在阵列上动态分配内存的算法:

  • 如果数组已满,我将创建一个两倍大小的新数组,并复制项
  • 如果数组已满四分之一,我将创建一个大小为一半的新数组,并复制项
这是一个相当快速的动态内存分配算法,尽管将元素复制到新分配的数组会有额外的开销

  • 什么是更快的,
    List
    或基于数组的算法?你建议用什么

  • List
    是否使用简单数组作为内部数据结构

  • List
    在内部使用数组,它使用与您类似的策略-如果长度超过数组的长度,它将使数组的大小加倍。然而,如果尺寸小得多,它不会使它变小

    mscorlib
    中的相关方法:

    private void EnsureCapacity(int min)
    {
        if (this._items.Length < min)
        {
            int num = (this._items.Length == 0) ? 4 : (this._items.Length * 2);
            if (num < min)
            {
                num = min;
            }
            this.Capacity = num;
        }
    }
    
    private void-rescapacity(int-min)
    {
    如果(此项长度
    数组的大小调整实际上发生在
    列表的setter中。Capacity

    是的,
    列表在内部使用
    T[]
    来保存对象


    据我记忆中的.NET4.0源代码所示,在添加新对象之前,它确保数组有足够的容量容纳新数量的对象。如果现有数组不能容纳新数量的对象,它将被一个两倍大小的新数组替换,所有对象和所有现有引用都将复制到新数组。

    除非您有特定的理由相信不是这样,否则使用C#附带的库几乎是一个普遍的好主意。这些实现都得到了很好的实现、调试和测试

    您描述的数据结构是动态数组数据结构的标准实现,大多数语言都将此作为默认列表实现。综上所述,
    List
    似乎使用了这个实现,因为它的文档引用了一个内部容量,只要大小小于容量,就可以保证O(1)append

    简言之,除非你不得不,否则避免重新发明轮子

    希望这有帮助

    这就是
    列表
    (以及许多其他语言的动态数组)的基本功能。调整大小的因素可能不同,我认为在删除元素时,它不会自行收缩备份阵列-但是有
    TrimToSize
    ,您可以自己设置
    Capacity
    ,如果客户端代码很好地使用此功能,这可能会允许更有效的策略。但基本上,它是渐近等价的


    至于使用哪一种:除非你有冷的、硬的数据,
    List
    不适合你的用例,并且差异很重要(你显然还不具备这方面的知识),否则你应该使用它。您自己的实现将有缺陷,功能不丰富(参见
    IEnumerable
    IList
    ,多种方法),优化程度较低,不易被广泛识别,不被其他库接受(因此您可能需要创建昂贵的副本,或者至少要做比使用
    列表
    更多的工作才能进行交互),很可能什么也得不到。

    回答您的问题:

    的确,C#的
    List
    实现使用了一个内部数组

  • 可序列化
  • 线程安全
  • 实现
    IEnumerable
    (这意味着它可以被LINQ查询,
    foreach
    ed等)
  • 二进制搜索
  • 等等

    因此,我要求您使用
    列表
    而不是您自己的列表

    哦,顺便说一句,如果你想从微软获得
    列表
    源代码,那么就在这里

    编辑

    List
    EnsureCapacity
    的源代码为:

        // Ensures that the capacity of this list is at least the given minimum
        // value. If the currect capacity of the list is less than min, the
        // capacity is increased to twice the current capacity or to min,
        // whichever is larger.
        private void EnsureCapacity(int min) {
            if (_items.Length < min) {
                int newCapacity = _items.Length == 0? _defaultCapacity : _items.Length * 2;
                if (newCapacity < min) newCapacity = min;
                Capacity = newCapacity;
            }
        }
    
    //确保此列表的容量至少为给定的最小值
    //价值观。如果列表的当前容量小于最小值,则
    //容量增加到当前容量的两倍或最小值,
    //以较大者为准。
    私人无效保证资本(整数最小值){
    如果(_项目长度
    无需重新发明车轮

    从MSDN:

    容量是列表中可以存储的元素数 需要在调整大小之前执行,而Count是元素数 实际上在列表中)

    容量始终大于或等于计数。如果计数超过 容量在添加元素时,容量将增加 在复制旧阵列之前自动重新分配内部阵列 元素并添加新元素

    通过调用TrimOverse方法或 显式设置容量属性。当容量的价值 如果显式设置,则内部数组也将重新分配给 容纳指定的容量,并复制所有图元

    检索此属性的值是一个O(1)操作;背景 该属性是一个O(n)操作,其中n是新容量


    它使用的是
    T[]
    数组,而不是
    List[]
    。既然可以查看CLR的代码,为什么还要猜测呢。它的开源:-)-检查我的答案如果你想缩小内部阵列,当然可以“手动”完成。调用
    trimOverse()
    方法,或者设置
    Capacity
    属性(其setter是公共的)。