数组与链表的优缺点和区别

1.数组:

数组是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。但是如果要

在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的

道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素。如果应用需要快速访问数据,很少插入和

删除元素,就应该用数组。

2.链表:

链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起,每个结点包括两个部分:一个是存

储数据元素 的数据域,另一个是存储下一个结点地址的 指针。如果要访问链表中一个元素,需要从第一个元素始,

一直找到需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了,只要修改元素中的指针就可以

了。如果应用需要经常插入和删除元素你就需要用链表。

3.区别:

(1)存储位置上:

数组逻辑上相邻的元素在物理存储位置上也相邻,而链表不一定;

(2)存储空间上:

链表存放的内存空间可以是连续的,也可以是不连续的,数组则是连续的一段内存空间。一般情况下存放相同多的数

据数组占用较小的内存,而链表还需要存放其前驱和后继的空间。

(3)长度的可变性:

链表的长度是按实际需要可以伸缩的,而数组的长度是在定义时要给定的,如果存放的数据个数超过了数组的初始大

小,则会出现溢出现象。

(4)按序号查找时,数组可以随机访问,时间复杂度为O(1),而链表不支持随机访问,平均需要O(n); 

(5)按值查找时,若数组无序,数组和链表时间复杂度均为O(1),但是当数组有序时,可以采用折半查找将时间复

杂度降为O(logn); 

(6)插入和删除时,数组平均需要移动n/2个元素,而链表只需修改指针即可; 

(7)空间分配方面: 

数组在静态存储分配情形下,存储元素数量受限制,动态存储分配情形下,虽然存储空间可以扩充,但需要移动大量

元素,导致操作效率降低,而且如果内存中没有更大块连续存储空间将导致分配失败; 即数组从栈中分配空间,,对

于程序员方便快速,但自由度小。

链表存储的节点空间只在需要的时候申请分配,只要内存中有空间就可以分配,操作比较灵活高效;即链表从堆中分

配空间, 自由度大但申请管理比较麻烦。

### 数组优缺点 - **优点**: - 支持随机访问,按下标进行随机访问的时间复杂度为O(1),可以快速定位到数组中的任意元素,适合需要频繁访问特定位置元素的场景。 - CPU高速缓存命中率比较高,由于数组空间连续,CPU在遍历过程中,一次加载数据时可以把数组很多数据都换存进寄存器缓存,提高了访问效率。 - 逻辑上相邻的元素物理上也相邻,在进行一些算法操作时,如排序、二分查找等,数组的结构更适合,能更好地发挥算法的性能[^1][^2][^3][^4]。 - **缺点**: - 头部中部的插入删除效率低,时间复杂度为O(N)。因为数组是从开始的位置连续存储数据,在头部或中间插入或删除数据时,需要挪动大量元素。 - 空间不够时需要增容,存在一定程序的性能消耗空间浪费。扩容分原地扩容异地扩容,异地扩容效率非常低,且为了避免频繁扩容,一般扩2倍,可能导致空间浪费。例如原空间有100个元素,满了扩容到200个,若只再插入5个元素,就会有95个空间浪费,且删除数据多了也不会释放空间[^1][^2][^3]。 ### 链表优缺点 - **优点**: - 按需求申请内存,需要存一个数据就申请一块内存,不存在空间浪费。 - 在任意位置插入删除数据的时间复杂度为O(1),操作效率高,适合需要频繁进行插入删除操作的场景。 - 链表采用随机存储的存储方法,不要求内存连续,靠next指针关联起来,适合写操作多、读操作少的情况[^1][^2][^3]。 - **缺点**: - 不支持下标的随机访问,查找元素需要从头节点开始顺序访问,查找的时间复杂度为O(n)。 - 链表在物理上不连续,每个节点都需要申请,在存储上有一定的消耗,例如存储多个节点时需要多个结构体,每个结构体里还需存指针。 - CPU高速缓存命中率低,存在缓存污染,因为链表空间不连续,不太会被一次缓存进去[^1][^2][^3]。 ### 数组链表区别 - **内存分配**:数组是静态分配内存,元素在内存的栈区,系统自动申请空间;链表是动态分配内存,结点元素在内存的堆区,每个元素须手动申请空间[^2]。 - **存储方式**:数组的元素在内存中是连续存储的;链表的节点在内存中是离散存储的,通过指针相连。 - **插入删除操作**:数组插入删除元素时,可能需要移动大量元素,效率较低;链表插入删除元素只需修改指针,效率较高。 - **随机访问**:数组支持随机访问,可通过下标直接访问元素;链表不支持随机访问,只能从头节点开始顺序访问。 ```python # 数组示例 array = [1, 2, 3, 4, 5] print(array[2]) # 随机访问 # 链表示例 class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next # 创建链表 1 -> 2 -> 3 head = ListNode(1) head.next = ListNode(2) head.next.next = ListNode(3) # 顺序访问链表 current = head while current: print(current.val) current = current.next ```
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值