数据结构与算法面试要点简明教程(三)—— 线性表

 

参考:https://blog.csdn.net/jiaoyangwm/article/details/80808235

https://blog.csdn.net/a2392008643/article/details/81781766

https://mp.weixin.qq.com/s/vn3KiV-ez79FmbZ36SX9lg

 

本文仅是将他人博客经个人理解转化为简明的知识点,供各位博友快速理解记忆,并非纯原创博客,如需了解详细知识点,请查看参考的各个原创博客。

目录

第三章  线性表

3.1  线性表的顺序存储结构

3.2  线性表的链式存储结构

3.3  相关面试题


第三章  线性表

线性表(List):由同类型数据元素构成有序序列的线性结构。

  • 元素之间是有顺序的:第一个元素无前驱,最后一个元素无后继,其他元素都有前驱和后继

  • 线性表是有限的

线性表可以利用数组来实现(顺序存储结构),也可以用链表来实现(链式存储结构)。

3.1  线性表的顺序存储结构

顺序存储结构:用一段地址连续的存储单元一次存储线性表的数据元素

顺序存储结构的三个属性:

  • 存储空间的起始位置:数组data,它的存储位置就是存储空间的起始位置
  • 线性表的最大存储容量:数组长度MaxSize
  • 线性表的当前长度:length
顺序存储结构

顺序存储结构中

  • 获取元素的时间复杂度为O(1)
  • 插入元素的平均时间复杂度为O(n)。插入最后一个位置时间复杂度为O(1),插入第一个位置时间复杂度为O(n)
  • 删除元素的平均时间复杂度为O(n)。删除最后一个位置时间复杂度为O(1),删除第一个位置时间复杂度为O(n)

3.2  线性表的链式存储结构

链式存储结构:用一组任意的存储单元存储线性表的数据元素。(这组存储单元可以是连续的,也可以是不连续的,即这些数据元素可以存在内存中未被占用的任意位置)

链式存储结构中的每个结点包含:存储数据元素信息的域(数据域)+存储后继元素地址的域(指针域)

  • 单链表:每个结点只包含一个指针域的线性链表
  • 双向链表:每个结点包含两个指针域,分别指向直接前驱和直接后继
链式存储结构示例图
  • 头指针:头指针是指向链表第一个结点的存储位置的指针,其是链表的必要元素。
  • 头结点:第一个结点前设一个结点,可以不存储任何信息,也可以存储长度等附加信息,其是为了操作的统一和方便而设置的,不是链表的必要元素。
带头结点的链表

 

空链表

在链式存储结构中:

  • 获取元素,需要从头开始找,直到第i个元素未知,时间复杂度为O(n)
  • 插入和删除元素,只需要简单改变结点的后继即可,时间复杂度为O(1)

注:无论是顺序结构还是链式结构(逻辑结构),都可以用数组和链表(物理结构)来实现。两者的特点如下:

数组的特点:数组将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素(内存地址固定累加),也就是说,其随机读取效率很高,但插入、删除效率低。同时,数组需要预留空间,在使用前要先申请占内存的大小,可能会浪费内存空间。并且数组不利于扩展,数组定义的空间不够时要重新定义数组。

//声明并初始化一个一维数组
int arr1[m];
memset(arr1, 0, m);
//声明一个多维数组
int arr2[m][n][k];
int *arr3 = new int[m][n][k];

链表的特点:链表的元素在内存中任意存放,通过存在元素中的指针联系到一起。其插入和删除效率高,访问元素效率低。同时,链表不用指定大小,扩展方便,内存利用率高。

//声明链表结点结构体
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
//创建一个结点
ListNode* node = new ListNode(1);

3.3  相关面试题

Q:数组和链表的区别?

A:如上所述。

Q:有什么方法能结合数组和链表的优点?

A:哈希表是数组和链表的折中方案,增加,删除,改写数据的复杂度平均都是O(1),效率非常高。

Q:如何防止数组越界?

A:1)检查传入参数的合法性;2)传参时把数组和数组长度一起传;3)打印数组索引方便检查;4)使用异常捕获。

Q:判断两个链表是否相交?

A:链表相交之后,后面的部分节点全部共用,可以用2个指针分别从这两个链表头部走到尾部,最后判断尾部指针的地址信息是否一样,若一样则代表链表相交。

Q:找出相交链表开始相交的结点?

A:首先计算出两个链表的长度,然后设置两个指针分别指向两个链表,让指向长的链表先走长度的差值步(长链长度-短链长度),此后两个指针一起走,直到找到相等的节点。

Q:判断单链表是否有环?

A:定义快慢指针,同时从链表的头结点出发,快指针每次走两步,慢指针每次走一步。如果快指针和慢指针相遇,则链表有环。此时,若要找出入环结点,可以在相遇后令快指针回到头结点,两个指针每次均走一步,第二次相遇的结点即为入环的第一个结点。

Q:给定一个链表的头指针和结点指针,用O(1)时间删除它?

A:用下一个节点数据覆盖要删除的节点,然后删除下一个节点。但是如果节点是尾节点时,该方法就行不通了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值