IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 关于数组和链表的常见误区 -> 正文阅读

[数据结构与算法]关于数组和链表的常见误区


前言

数据结构与算法,从基础的数据结构开始回顾,然后一直到算法深入,记录一些算法心得和笔记。知识输出才不容易遗忘,也方便自己随时复习学过的知识,然后每日一总结今天的算法刷题。


提示:以下是本篇文章正文内容。

一、关于数组的误区

刚学习数据结构这门课的同学,问起数组的特点,可能会回答到查找方便,查找时间复杂度为O(1),插入和删除效率低,时间复杂度为O(n)。

乍一听好像没有毛病。其实是有错误的。
数组是一个线性表,内存地址连续,存储同一数据类型。访问一个下标为 i 的数据的值时,其内存地址为 地址= 基地址 + i * type_data 。type_data为 该数组的数据类型的大小,int类型为4 字节。应该说的是数组的随机访问效率高,时间复杂度为 O(1)。如果是查找的话,就连一个排好序的数组,利用二分算法,它的查找时间复杂度也为 O(logn)。

如何解决插入效率低的问题呢?
插入优化:因为插入时,插到数组中间为 i 的下标时,需要移动后面 n- i 位,插入到第一个位置,它的时间复杂度就是O(n)。但是我们插入到最后一个位置时,它的随机访问可以使时间复杂度为O(1)。我们要是每一次插入或删除都移动后面所有位的数据的话,就很影响效率。所以我们要尽量在数组末尾插入。因此:插入一个下标为 i 的值时,可以直接将原来的值放到数组最后,再将该下标位置替换为新值,最后删除最后的元素即可。时间复杂度就为O(1)。

如何解决删除效率低的问题?
删除优化:如果直接删除数组中某一位置元素,需要向前移动后面所有元素的位置,避免造成数组内存的浪费。时间复杂度就是O(n)。但是我们可以不用每一次删除都直接实际删除,可以把将要删除的位置 标为待删 ,每次删除并不是真的删除,只是记录待删的数据,最后在内存不够时,就将多次删除操作集中执行,这样就大大减少了数据多次搬移的消耗。

二、关于链表的误区

链表地址不连续,不支持随机存储,查找效率为O(n),删除或者插入某个结点的时间复杂度为O(1)。
需要说明的是,其实这种说法是不太准确的,或者说是有先决条件的。这个删除或插入的操作是指纯删除或插入,由于单向链表只记录了后继结点的指针,但是删除和插入都还需要前驱指针,所以O(1)的复杂度是忽略了从头到尾查找前驱对查找消耗的。

单向链表:

比如,其中删除操作有两种情况:

  1. 删除结点中值等于某个给定值 的结点
  2. 删除给定指针指向的结点

第一种情况:是需要从头到尾查找一遍,比较值的大小的,所以这种情况时间复杂度为O(n).
第二种情况:使前一个指针指向该指针的下一个值,但是需要前驱指针,所以时间复杂度也为O(n)。
插入情况与删除情况相同。

双向链表:

针对单向链表的第二种情况,已经找到要删除的结点,但是我们需要找到该结点的前驱结点,而单链表并不支持直接获取前驱结点,所以,为了找到前驱结点还是要从头到尾开始遍历链表,找到前驱结点。

但是对于双向链表,由于结点保存了前驱和后继的结点的指针,可以直接找到前驱指针,因此针对第二种情况时间复杂度就变为O(1)。因此可以知道,双向链表插入和删除都比单向链表更加灵活高效,还支持双向循环。

而除了插入和删除有优势,对于一个有序链表,双向链表的按值查找效率也要比单链表高。因为可以记录上次查找的位置p,每次查找时,根据要查找的值与p的大小关系,决定向前还是向后查找。所以平均只需要查找一半的数据

链表实现LRU算法

LRU是操作系统的缓存淘汰算法的最近最久未使用淘汰策略。可以使用单向链表实现该算法。
步骤:
1.顺序遍历链表
2.如果该数据已经在链表中,则删除原位置的该节点,然后再将它插入到链表的头部。
3.如果该数据没有在链表中,又分为两种情况:
a)如果缓存未满,直接加到链表的头部
b)如果缓存已满,则将链表尾部的结点删掉,将它插入到链表的头部。


总结

以上就是关于数组和链表的一些误区,也能更好地理解这两种最基础的数据结构。很多其他数据结构都是在这两种基础结构中,构建起来的,比如队列、栈、树等结构,都可以用数组或者链表实现。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-10 11:38:31  更:2021-07-10 11:38:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/5 11:07:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码