链表和顺序表的取舍(详解)

链表的定义:

(1)链表的初始化

        链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。每个节点都是通过指针相互连接的,形成一个链式结构。

如图: 每个节点是以 next 指针相连,可以很直观的看到链表在物理上和在理论上都是不连续的。

链表的定义方式如下:(其中data是用来存储有效数据,而 next 指针是指向下一个 节点 (也就是下图中的 struct SListNode)

(2)链表的增加操作

由于链表物理空间的不连续性,所以链表在进行增加操作时的效率是很高的。如下图:

把节点 Z 增加到 节点 A 后面,只需两步即可。

1.将 Z 节点的 next 指针指向 B( 此时不能直接断开 A节点的 next指向,否则将会找不到 B 节点)

2. 将 A 节点的 next 指针指向 Z (这两步的顺序不能颠倒)

这样就完成了链表的增加操作。

(3)链表的删除操作 

还是那句话:由于链表物理空间的不连续性,链表在进行删除操作时的效率是很高的。如下图:删除B 节点操作。也是非常简单,一步到位。

在更改 A->next 前,A->next是指向 B,所以 A->next = A->next->next 就是将 A 的 next 指针指向 节点 C. 此时 B节点就被架空了(删除了) 。( B 节点可以先存储起来,再让它的 next 指针指向 NULL)

(4)链表的查找操作

链表查找,我们看这个逻辑结构就知道,物理地址的不连续导致我们只能通过 指针 next ,从头开始查找 , 所以这个查找的效率是很慢的,这一点远远比不上 顺序表。

顺序表的定义:

(1)顺序表的初始化

        顺序表是一种线性数据结构,它是由一组连续的存储单元(通常是数组)组成的数据结构。在顺序表中,数据元素之间的逻辑关系与物理关系是一致的,即相邻的元素在内存中也是相邻的。

如图: 顺序表是需要开辟一段完整的空间,可以很直观的看到链表在物理上和在理论上都是连续的。(数组的物理空间和理论空间都是连续的)

顺序表的定义方式如下: 为了避免初始化定义空间不足,采用 int*a 来定义数组,使得数组能够动态的开辟新空间,改变数组容量。

(2)顺序表的增加操作

若在顺序表的末尾增加节点,效率会嘎嘎高,但是若不在末尾增加就要考虑到移动节点的问题:

如图若想将节点 A 插入到地址为 009FFDB 的位置(data3之前),由于顺序表以数组实现,则需要移动 data3到data4的位置,这样才使得 A 能放到地址为 009FFDB 的位置。

这样已经相当繁琐了,加入我们是在数组头部插入 A 呢 ? 显而易见,顺序表中元素的移动将会更加频繁,这样大大的减少了代码效率;

(3)顺序表的删除操作

同样的,由于顺序表是以 数组 实现,在尾部删除数据非常简单,但是若不在末尾增加就要也考虑到移动节点的问题:

如图: 倘若删除 data1节点(即顺序表头节点),data1 之后的元素只能向前补位,倘若有 n 个元素,此时则要移动 n-1 次,可见顺序表的删除操作非常极端。

(4)顺序表的查找操作

我们可以通过下标元素来直接访问元素,从而对顺序表进行查找操作。我们只需控制下标,通过data来和目标值比对即可完成查找,最极端的情况就是遍历整个数组。倘若是有序的序列,查找操作的过程还会被大大简化。

对比:

单链表的优点:
1. 插入和删除操作方便快捷,只需修改指针即可。
2. 不需要预先分配存储空间,可以动态地分配和释放内存。
3. 可以方便地实现递归操作。

单链表的缺点:
1. 查找操作效率较低,需要遍历整个链表才能找到目标元素。
2. 无法直接访问前一个元素,需要从头开始遍历。
3. 需要额外的空间来存储指针信息。

顺序表的优点:
1. 查找操作效率高,可以通过下标直接访问元素。
2. 内存空间利用率高,不需要额外的指针存储空间。
3. 适合于静态数据集合,不需要频繁的插入和删除操作。

顺序表的缺点:
1. 插入和删除操作效率低,需要移动大量元素。
2. 静态分配内存空间,容量固定,无法动态扩展。
3. 插入和删除操作可能导致内存碎片化。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值