C++中数组和链表的区别?

78 阅读5分钟

C++中数组和链表的区别?

公众号:阿Q技术站

1. 数组(Array)

数组是一种固定大小的线性数据结构,用来存储多个相同类型的元素。数组的大小在编译时就确定,数组的元素在内存中是连续存储的。

特点
  • 固定大小:数组在声明时需要指定大小,大小一旦确定无法更改。
  • 元素连续存储:数组的元素在内存中是连续存储的,这意味着可以通过下标快速访问元素。
  • 随机访问:可以通过下标访问任何位置的元素,时间复杂度为O(1)。
  • 内存效率:数组的内存分配是一次性的,没有额外的内存开销,适合存储小型数据。
优缺点
优点:
  • 访问速度快:因为数组的元素是连续存储的,可以通过下标快速访问。
  • 内存使用效率高:数组在内存中占用的空间是连续的,没有额外的内存开销。
缺点:
  • 大小固定:数组的大小在声明时必须指定,一旦创建后不能改变。若需要动态调整数组大小,需要创建新的数组并复制数据。
  • 插入和删除操作效率低:插入和删除元素时需要移动大量的元素,尤其是在数组的中间位置,时间复杂度为O(n)。
示例代码
#include <iostream>
using namespace std;
​
int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    
    // 通过下标访问元素
    cout << "First element: " << arr[0] << endl;  // 输出: 1
    cout << "Second element: " << arr[1] << endl; // 输出: 2
​
    // 修改元素
    arr[2] = 10;
    cout << "Modified third element: " << arr[2] << endl; // 输出: 10
​
    return 0;
}
解释
  • arr[5] 是一个大小为 5 的数组,元素在内存中连续存储。
  • 可以通过下标访问和修改数组中的元素。
  • 数组在声明时大小固定,不能动态调整。

2. 链表(Linked List)

链表是一种由一系列节点(Node)组成的数据结构,每个节点包含数据和指向下一个节点的指针。链表的大小可以动态变化,节点之间在内存中不需要是连续存储的。

特点
  • 动态大小:链表的大小在运行时可以动态增长或缩小,可以随时插入和删除元素。
  • 节点非连续存储:链表的节点在内存中并不连续,每个节点包含一个指针,指向下一个节点。
  • 顺序访问:访问链表中的元素时需要从头节点开始,逐个遍历,直到找到目标节点,时间复杂度为O(n)。
  • 插入和删除效率高:由于不需要移动其他元素,插入和删除操作的时间复杂度为O(1),尤其是在链表头部或尾部操作时。
优缺点
优点:
  • 大小动态变化:链表不需要在编译时指定大小,可以在运行时根据需要进行插入和删除操作。
  • 插入和删除效率高:不需要移动其他元素,可以直接修改指针,插入和删除操作的时间复杂度为O(1),适合频繁插入和删除的场景。
缺点:
  • 访问速度较慢:访问链表中的元素需要从头节点开始逐个遍历,时间复杂度为O(n)。
  • 额外的内存开销:每个节点除了存储数据外,还需要存储指向下一个节点的指针,增加了内存开销。
示例代码
#include <iostream>
using namespace std;
​
class Node {
public:
    int data;
    Node* next;
    
    Node(int val) : data(val), next(nullptr) {}  // 构造函数初始化节点
};
​
int main() {
    // 创建链表节点
    Node* head = new Node(1);
    head->next = new Node(2);
    head->next->next = new Node(3);
​
    // 遍历链表
    Node* current = head;
    while (current != nullptr) {
        cout << "Node data: " << current->data << endl;
        current = current->next;
    }
​
    return 0;
}
解释
  • Node 类表示链表的节点,每个节点包含一个数据字段 data 和一个指向下一个节点的指针 next
  • 通过指针连接各个节点,形成链表。
  • 遍历链表时需要从头节点开始,逐个访问每个节点,直到到达链表末尾。

3. 数组和链表的比较

特性数组(Array)链表(Linked List)
存储结构元素在内存中连续存储每个节点在内存中不连续,节点通过指针连接
大小大小在编译时确定,不能动态改变动态大小,可以在运行时调整
访问方式随机访问,可以通过下标直接访问元素顺序访问,需要从头节点开始逐个遍历
插入与删除效率插入和删除时需要移动大量元素,效率较低插入和删除操作较高效,尤其是在链表的头部或尾部插入
内存使用效率内存分配是一次性的,没有额外开销每个节点需要额外存储一个指针,增加了内存开销
适用场景适合频繁访问数据且元素个数固定的情况适合频繁插入和删除元素,且数据量不固定的情况
访问速度访问速度快,O(1)访问速度慢,O(n)
内存连续性存储位置连续存储位置不连续
适用场景:
  • 数组:

    • 适合用于数据量固定、并且频繁访问元素的场景,如实现查找、排序等算法。
    • 如果程序需要快速随机访问,数组是一个理想选择。
  • 链表:

    • 适合用于需要频繁插入和删除元素的场景,尤其是在数据量不固定的情况下。
    • 比如实现队列、栈等动态数据结构,或者需要动态增长/缩小的情况。

4. 总结

  • 数组在内存中是连续的,能够提供快速的随机访问,但大小固定,插入和删除操作效率较低,适用于数据量小且访问频繁的场景。
  • 链表是由一系列节点组成的,能够动态增长或缩小,插入和删除操作效率较高,但访问速度较慢,适用于数据量动态变化、需要频繁插入和删除的场景。

选择数组还是链表,取决于你的需求:如果需要快速的访问和固定大小的数据,数组更合适;如果需要频繁地插入和删除,链表则是更好的选择。