数组和链表 Array and Linked-List

数据结构概述 Data Structure Overview

数据结构本质上就是数据的存储方式。常见数据结构分为线性表(Linear List)和非线性表。

线性表

线性表是一种比较简单的数据结构,其中的元素是一对一的关系,每个元素只有前后两个方向。线性表包括数组、链表、队列、栈等。
在这里插入图片描述

非线性表

非线性表中的元素是一对多或多对一的关系,元素之间不只有前后两个方向。非线性表包括树和图等。
在这里插入图片描述

数组 Array

数组是一种顺序表,属于线性存储结构,存储在一段连续的内存空间。
在这里插入图片描述

数组的随机访问

数组是存储在一块连续的内存中,并且数组中元素数据类型相同。因此,可以实现对数组的随机访问。例如对于数组 a[10],要访问 a[i],可以直接得到其地址:首地址 + i * sizeof(int)。

这也是数组这种顺序表的一个优势:高效地访问某个元素,也即随机访问。

数组的插入

由于数组是存储在一块连续的内存中,那么对数组的插入注定是比较低效的,需要做整块数据的搬移。
在这里插入图片描述

数组的删除

和插入类似,删除元素也是低效的。
在这里插入图片描述

链表 Linked-List

数组是连续存储的,并且元素顺序是通过下标来决定的。而链表可以不是连续存储的,它的元素顺序是由链表中的指针决定。和数组相比较,链表的插入和删除效率很高,而访问第 k 个元素效率较差。

链表的典型结构和数据结构如下,这里需要注意:箭头的目的是指向链表中的一个节点(下同)。
在这里插入图片描述

struct ListNode {
   int key;
   ListNode *prev;
   ListNode *next;
   ListNode(int x) : val(x), prev(nullptr), next(nullptr) {}
 };

链表的分类

双链表:上面给的典型结构就是双链表,next 指向下一个节点, prev 指向前一个节点。
单链表:不包含 prev 指针。
循环链表:一种特殊的单链表,链表的尾结点 next 指向链表的头结点。
双向循环链表:一种特殊的双向链表,链表的表头 prev 指向表尾节点,表尾 next 指向表头节点。
在这里插入图片描述

链表的基本操作

以双向链表为例,介绍下链表的基本操作。链表的插入和删除不需要维护存储的连续性,效率很高。但是,元素的访问无法像数组那样随机访问,需要逐个遍历节点。

在这里插入图片描述

链表的搜索

链表的搜索指的是查找链表中第一个关键字为 k 的元素,并返回指向该元素的指针。

LIST-SEARCH(L, k)
x = L.head
while x != NIL and x.key != k
  x = x.next
return x

链表的插入

链表的插入是指将关键字为 k 的元素 x 插入到链表的前端。

LIST-INSERT(L, x)
x.next = L.head
if L.head != NIL
  L.head.prev = x
L.head = x
x.prev = NIL

链表的删除

链表的删除是指将元素 x 从链表中移出。若是是给定的是 key 值,则先调用链表的搜索算法找到 x,再执行下面的删除算法。

LIST-DELETE(L, x)
if x.prev != NIL
  x.prev.next = x.next
else L.head = x.next
if x.next != NIL
  x.next.prev = x.prev

参考

  • 算法导论
  • 数据结构和算法之美
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值