【问题标题】:difference between array and list数组和列表的区别
【发布时间】:2011-03-30 01:12:22
【问题描述】:

数组和列表有什么区别?

【问题讨论】:

  • C 中有列表吗?我的意思是,除了数以百计的链接列表的简约书籍示例之外?

标签: c


【解决方案1】:

在 C 中,数组是一个固定大小的连续存储区域,包含多个对象,一个接一个。这个数组是 C 赋予单词含义的“对象”——基本上只是一些代表某物的内存。一个对象可能只是一个int

您可以稍微区分数组objects和数组types。人们经常使用数组objects,它使用malloc 分配,并通过指向第一个元素的指针使用。但是 C 也有不同大小的数组的特定类型,也有可变长度数组的特定类型,它们的大小在创建时设置。 VLA 有一个有点误导性的名称:大小只是“可变”的,因为它在编译时不是固定的。它在对象的生命周期内不能改变。

所以,当我说数组是固定大小时,我的意思是一旦创建数组,大小就不能改变,这包括 VLA。有realloc,它在逻辑上返回一个指向替换旧数组的新数组的指针,但有时可以返回传入的相同地址,已更改数组的大小。 realloc 作用于内存分配,而不是一般的数组。

这就是数组。 C 编程语言没有定义任何称为列表的东西。无法真正将定义明确的内容与未定义的内容进行比较;-) 通常“列表”表示linked list,但在某些情况下或在其他语言中,它表示其他内容。

就此而言,在其他语言中,“数组”可能意味着其他东西,尽管我无法立即想到一种语言,它的含义与 C 数组完全不同。

如果您的问题确实与 C 无关,并且是与语言无关的数据结构问题,“数组和链表有什么区别?”,那么它就是这个的副本:

Array versus linked-list

【讨论】:

  • “我无法立即想到一种语言,其中 [array] 的含义与 C 数组完全不同。”看PHP的“数组”数据结构;这是我能想到的最不一样的。
【解决方案2】:

C 中没有标准列表这样的东西。C++ 中有这样的东西,它被实现为double-linked list

主要区别在于数组具有随机访问权限 - 您可以在O(1) 时间内访问数组的任何成员(即如果a 是一个数组,a[4])并且有一个在编译时预设大小。链表有顺序访问——要访问一个元素,你必须遍历列表直到你找到你想要的元素(即如果b 是一个链表,要到达b 的第5个元素你会拥有遍历元素 0、1、2、3 和 4),并且大小可以动态增长和缩小。

【讨论】:

  • @Stephen:虽然我可能会指出,数组也可以在运行时使用动态内存分配设置它们的大小 - 它没有必须在编译时定义,由程序员来选择
  • 每个元素的大小是在编译时设置的,所以你可以动态创建一个并不会改变查找是O(1)的事实
  • @bguiz 据我所知,纯数组的大小在编译时设置。您的意思是使用malloc 和指向类型的指针来进行动态内存分配吗?
  • @Stephen:C99 中也有 VLA。对于除 Microsoft 之外的所有人来说,C99 是“当前”C,而 C89 是“旧”C。但我认为 bguiz 的意思只是 malloc
  • @Stephen @Steve Jessop :关于 C 的 IDK,在 C++ 中,如果在初始化数组时使用 new 运算符,则它是在堆上创建的,而不是在堆栈上,它的大小在运行时
【解决方案3】:

虽然 没有什么像 list in C per se 但你肯定会谈论链表实现.

数组:随机访问,预定义大小。
链表:顺序访问,运行时大小。

其他语言,比如 Python,可能同时内置了 lists 和 arrays,它们的含义可能不同。

下面有用的 cmets:

您可以添加数组列表。列表内部是一个数组,需要时加倍,只有 1/4 满时减半。这为添加、删除、获取(索引)摊销提供了 O(1)。 – lasseespeholt

Python 的list 不是链表。而 Python listarray 之间的区别是 list 可以存储任何内容,而数组只能存储原始类型(intfloat 等)。 – KennyTM

【讨论】:

  • Python 的list 不是链表。而 Python listarray 之间的区别是 list 可以存储任何东西,而 array 只能存储原始类型(int、float 等)。
  • 您可以添加数组列表。列表内部是一个数组,需要时加倍,只有 1/4 满时减半。这为添加、删除、获取(索引)摊销提供了 O(1)。
  • Python 的“列表”实际上就是其他语言所说的数组(动态大小)。
  • 伙计们,对于 Python 行,我只是建议有些语言具有区别和内置类型。
【解决方案4】:
  1. 对于数组,它有一个固定的大小,就像我们写的那样,new int [100] 但是列表没有固定的大小......它可以继续下去

  2. 在列表中插入和删除比在数组中更容易 原因:链表可以简单地改变插入和删除的指针,而数组的插入和删除需要shiftRight和shiftLeft

  3. 链表使用虚拟头节点来避免插入空列表或从单位大小列表中删除最后一个节点的特殊情况;并且,它使用双链接来允许在两个方向上进行迭代。成本当然是容纳虚拟节点所需的额外空间(最小成本),以及额外的前一个链接以及每个节点通常的下一个链接(更重要的成本)。 在数组中,我们可以借助它的随机访问来添加

  4. 在链表中,对尾节点的引用只是 header.prev,它使我们能够以恒定的时间追加到链表中(无需迭代查找尾引用,也无需维护单独的尾引用) . 但是在数组中,我们需要在插入之前重新调整数组的大小。

  5. 与链表不同,数组具有获得随机访问的灵活性。

链表有问题,如,

它为我们使用的指针消耗了额外的内存!

O(n) 的时间复杂度,而不是像数组中那样的 O(1)

单链表反向遍历比较困难,如果我们使用双向链表,另一个指针意味着更多的额外内存存储

还有堆限制!仅当堆中有可用空间时才分配内存。如果内存不足,则不会创建内存。

数组有问题,例如,

内存浪费或短缺的可能性。

希望这会有所帮助! :)

【讨论】:

    【解决方案5】:

    链接数据结构的一个经常被低估的特性是,您可以在由于元素之间没有连续的内存保证而导致内存高度碎片化的情况下使用它们。例如,您可能有 100MB 的可用空间,但只说最大运行长度为 10MB 的可用内存。在这种情况下,您只能创建一个大小为 10MB 的数组,但可能会创建一个更大的链表,因为您可以利用每次运行的空闲内存,这些内存足够大,可以包含单个节点。

    【讨论】:

      【解决方案6】:

      array 只有相似的数据类型(即)它们本质上是同质的。我们只能有一个字符串、整数等数组。数组的大小也是预定义的。 但在 list 的情况下,我们可以有任何类型的元素。让它成为一个字符串整数或两者的组合。列表中也允许空元素或重复元素。列表示例包括 arraylist ,linkedlist.here 列表中的大小可以随时增加或缩小。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-12
        • 1970-01-01
        • 1970-01-01
        • 2012-12-09
        • 2016-05-25
        相关资源
        最近更新 更多