数组

是一种线性表数据结构,它用一组连续的内存空间,来存储一组具有相同类型的数据。

使用了连续的内存空间和相同类型的数据,使得它可以“随机访问”,但同时也让数组的删除,插入等操作变得非常低效,

为了保证连续性,就需要做大量的数据搬移工作。 数组是从0开始编号的,目的是为了减少一次减法运算。

设计思想

空间换时间 & 时间换空间

空间换时间 :当内存空间充足的时候,为了追求代码更快的执行速度,

      就可以舍弃对存储空间的要求,从而追求效率。

时间换空间 :内存空间比较紧缺时,为了让程序稳定运行,

      就需要舍弃时间,极大满足对存储空间的要求。

缓存

实际上 就是利用了空间换时间的设计思想。如果我们把 数据存储在硬盘上,会比较节省内存,

但每次查找数据都要询问一次硬盘,会比较慢。

但如果我们通过缓存,提前将数据加载在内存中,虽然会比较消耗内存,但是查数据的速度就提高了。

对于执行较慢的程序,可以通过消耗更多内存(空 换 时)来优化

对于内存消耗过多的程序,可以通过消耗更多的时间(时 换 空)来降低内存的消耗

二维数组内存寻址公式

对于 m * n 的数组,a[i][j] (i<m,j<n)​的地址为:

address = base_address + (i*n+j)*type_size

链表的存储结构

数组需要一块连续的内存空间来存储,需要事先申请需要申请内存空间;

而链表通过“指针”将一组零散的内存块串联起来使用,不会占用还未使用的内存空间。

单链表

链表通过指针将一组零散的内存块串联在一起,内存块称为链表的“结点”。

每个链表的结点除了存储数据之外,还需要记录链上的下一个结点的地址,叫作后继指针 next。

循环链表

循环链表跟单链表的区在尾结点指针是指向链表的头结点。

双向链表

双向链表支持两个方向,每个结点同时有后继指针 next 指向后面的结点,

还有一个前驱指针 prev 指向前面的结点。

LRU-缓存

缓存是一种提高数据读取性能的技术,在硬件设计、软件开发中都有着非常广泛的应用,

比如常见的CPU缓存、数据库缓存、浏览器缓存。

常见的缓存淘汰策略

  先进先出策略 FIFO

  最少使用策略 LFU

  最近最少使用策略 LRU

思路:

维护一个有序单列表,越靠近链表尾部的节点越早之前访问的。

当有一个新的数据被访问时,从链表头开始顺序遍历链表:

1 如果此数据之前已经被缓存进链表中了,遍历得到这个数据对应的节点,

并将其从原来的位置删除,然后再插入到链表的头部

2 如果此数据没有在缓存链表中,则将此节点插入到链表的头部:

 如果此时缓存超过容量,则链表尾节点删除。

回文字符串: 是一个正读和反读都一样的字符串

判断思路 :

1使用快慢两个指针找到链表中点,慢指针每次前进一步,快指针每次前进2步,这样当快指针指向末尾时,

慢指针指向了中点。

2 在慢指针前进的过程中,同时修改其next指针指向上一个元素prev,使得链表前半部分反序

3 最后比较重点两侧的链表是否相等。

链表 VS 数组  (对比)

数组简单易用,在是线上使用的是连续的内存空间,可以借助CPU的缓存机制,

预都数组中的数据,所以访问效率更高

链表在内存中并不是连续存储,所以对CPU缓存不友好,没办法有效预读

缺点

数组的缺点是大小固定,一经声明就要占用整块连续内存空间。如果声明的数组过大,

系统可能没有足够的连续内存空间分配给它,导致“内存不足”。

如果声明的数组过小,则可能出现不够用的情况。

这时只能再申请一个更大的内存空间,把原数组拷贝进去,非常费时。

链表本身没有大小的限制,天然地支持动态扩容

如果 对 内存的使用非常苛刻数组就更合适,因为链表中的每个结点都需要消耗额外的存储空间去存储一份指向下一个节点的指针

所以内存消耗会翻倍

对链表进行频繁的插入、删除操作,会导致频繁的内存申请和释放,容易造成内存碎片,对于Python编程语言,

就有可能频繁的GC(Garbage Collection,垃圾回收)。

数组 & 链表的更多相关文章

  1. 数据结构java(一)数组链表

    链表是数据结构中最基础的内容,链表在存储结构上分成两种:数组形式储存,链式存储. 相比c语言需要的结构体,在java中由于有了面向对象编程,将指针‘藏’了起来,不需要分配内存. 所以只需要创建一个对象 ...

  2. jdk1.8 HashMap 实现 数组+链表/红黑树

    转载至 http://www.cnblogs.com/leesf456/p/5242233.html 一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Ja ...

  3. 数组链表下标指针map list

    1.时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间 ...

  4. 【C++】约瑟夫环(数组+链表)

    基于数组: #include<iostream> #include<cstring> #include<cstdlib> using namespace std; ...

  5. 【leetcode-88,21】 合并两个有序数组/链表

    合并两个有序数组 (easy,1过) 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nu ...

  6. JAVA并归排序(数组+链表)

    并归排序与快速排序相似,靠分治思想突破了排序算法 O(n2) 的瓶颈. 我们看回顾一下几大排序算法的时间.空间复杂度: 排序算法 平均时间复杂度 最坏时间复杂度 空间复杂度 是否稳定 冒泡排序 O(n ...

  7. C++归并排序(数组&链表)

    1.归并排序(Merge Sort) 归并排序的性能不受输入数据的影响,始终都是O(n log n)的时间复杂度.代价是需要额外的内存空间. 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采 ...

  8. 1032 Sharing (25分)(数组链表)

    To store English words, one method is to use linked lists and store a word letter by letter. To save ...

  9. 使用排序数组/链表/preorder构建二叉搜索树

    2018-08-13 11:29:05 一.Convert Sorted Array to Binary Search Tree 问题描述: 问题求解: public TreeNode sortedA ...

随机推荐

  1. 【雕爷学编程】Arduino动手做(57)---四档矩形波模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...

  2. 案例(一) 利用机器算法RFM模型做用户价值分析

      一.案例背景 在产品迭代过程中,通常需要根据用户的属性进行归类,也就是通过分析数据,对用户进行归类,以便于在推送及转化过程中获得更大的收益. 本案例是基于某互联网公司的实际用户购票数据为研究对象, ...

  3. 百度智能云平台调用食物识别api Java实现

    纪录一下我小学期2天花了20小时写的菜品识别java程序. 1.2. 百度智能云简介 1.2.1 百度图像识别服务 百度图像识别服务,基于深度学习及大规模图像训练,准确识别图片中的物体类别.位置.置信 ...

  4. Apache自定义404

    先用命令找到httpd.conf文件在哪 find -name 'httpd.conf' 默认配置文件: vim /etc/httpd/conf/httpd.conf 然后找到项目的路径 <Di ...

  5. DRF视图组件

    DRF视图组件: CVB模式继承----五层 from django.views import View # Django的View from rest_framework.views import ...

  6. 重学 Java 设计模式:实战工厂方法模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获!

  7. CF861D

    题目链接:http://codeforces.com/contest/861/problem/D 解题思路: 优雅的暴力. 对于输入的每一个号码,从短到长找出它的所有子串,用 vector 保存每个号 ...

  8. 【Java_集合框架Set】HashSet、LinkedHashSet、TreeSet使用区别

    HashSet:哈希表是通过使用称为散列法的机制来存储信息的,元素并没有以某种特定顺序来存放: LinkedHashSet:以元素插入的顺序来维护集合的链接表,允许以插入的顺序在集合中迭代: Tree ...

  9. 4、Servlet中的Cookie 用于存储 web 页面的用户信息。

    Servlet Cookie 处理 Cookie 是存储在客户端计算机上的文本文件,并保留了各种跟踪信息.Java Servlet 显然支持 HTTP Cookie. 识别返回用户包括三个步骤: 服务 ...

  10. AspectJ JoinPoint及ProceedingJoinPoint 简要api文档

    AspectJ使用org.aspectj.lang.JoinPoint接口表示目标类连接点对象,如果是环绕增强时,使用org.aspectj.lang.ProceedingJoinPoint表示连接点 ...