顺序存储跟链式存储有什么区别

292 阅读3分钟

顺序存储和链式存储是两种不同的数据存储方式,它们在实现线性表(如数组、链表)时有明显的区别。以下是它们的主要区别:


1. 存储方式

  • 顺序存储

    • 使用数组来存储元素。
    • 元素在内存中是连续存储的。
    • 通过下标(索引)可以直接访问元素。
  • 链式存储

    • 使用节点来存储元素,每个节点包含数据和指向下一个节点的指针。
    • 元素在内存中是非连续存储的。
    • 通过指针(引用)逐个访问元素。

2. 插入和删除操作

  • 顺序存储

    • 插入:需要移动元素腾出位置,时间复杂度为 O(n)
    • 删除:需要移动元素填补空缺,时间复杂度为 O(n)
    • 适合查找多、插入删除少的场景。
  • 链式存储

    • 插入:只需调整指针,时间复杂度为 O(1) (如果已知插入位置)。
    • 删除:只需调整指针,时间复杂度为 O(1) (如果已知删除位置)。
    • 适合频繁插入删除的场景。

3. 查找操作

  • 顺序存储

    • 通过下标可以直接访问元素,时间复杂度为 O(1)
    • 按值查找需要遍历数组,时间复杂度为 O(n)
  • 链式存储

    • 必须从头节点开始逐个遍历,时间复杂度为 O(n)
    • 无法通过下标直接访问元素。

4. 空间利用率

  • 顺序存储

    • 需要预先分配固定大小的内存空间。
    • 如果数组容量过大,可能浪费空间;如果容量不足,需要扩容(复制数据到新数组)。
  • 链式存储

    • 动态分配内存,按需创建节点。
    • 每个节点需要额外空间存储指针,空间利用率稍低。

5. 适用场景

  • 顺序存储

    • 适合元素数量固定或变化不大的场景。
    • 适合需要频繁随机访问元素的场景(如数组)。
  • 链式存储

    • 适合元素数量变化频繁的场景。
    • 适合需要频繁插入和删除的场景(如链表)。

6. 代码实现对比

顺序存储(基于数组)

class SeqList {
    private int[] data; // 数组存储元素
    private int size;   // 当前元素个数

    public void insert(int index, int value) {
        // 需要移动元素
        for (int i = size; i > index; i--) {
            data[i] = data[i - 1];
        }
        data[index] = value;
        size++;
    }
}

链式存储(基于链表)

class Node {
    int value;
    Node next;
}

class LinkedList {
    private Node head; // 头节点

    public void insert(int index, int value) {
        Node newNode = new Node(value);
        // 只需调整指针
        newNode.next = prev.next;
        prev.next = newNode;
    }
}

7. 总结对比表

特性顺序存储(数组)链式存储(链表)
存储方式连续内存非连续内存
插入/删除需要移动元素,O(n)调整指针,O(1)
查找随机访问,O(1)必须遍历,O(n)
空间利用率可能浪费或不足每个节点需要额外指针空间
适用场景查找多,插入删除少插入删除多,查找少

举个例子

  • 顺序存储:像一排连续的座位,找座位很快,但中间插入或离开一个人需要其他人挪动。
  • 链式存储:像一群人手拉手,插入或离开一个人只需松开手,重新拉手,但找某个人需要从头开始数。