当前位置: 首页 > news >正文

门户网站开发项目的风险游戏广告联盟平台

门户网站开发项目的风险,游戏广告联盟平台,全国建筑四库一平台查询个人信息,iis7 新建网站目录 1、链表的定义 2、链表的特点 3、为何要使用链表 4、数组与链表的区别 5、链表的增删查 5.1、在头部插入链表 5.2、在中间插入链表 5.3、删除头节点 5.4、删除中间节点 5.5、查询某个值 6、链表的应用 6.1 如何设计一个LRU缓存算法? 6.2 约瑟夫问题 1、链表的定…

目录

1、链表的定义

2、链表的特点

3、为何要使用链表

4、数组与链表的区别

5、链表的增删查

5.1、在头部插入链表

5.2、在中间插入链表

5.3、删除头节点

5.4、删除中间节点

5.5、查询某个值

6、链表的应用

6.1 如何设计一个LRU缓存算法?

6.2 约瑟夫问题


1、链表的定义

链表通过指针将一组零散的内存块串联在一起。其中,我们把内存块称为”结点“。为了将所有的结点串起来,每个链表的结点除了存储数据之外,还需要记录链上的下一个结点的地址。

2、链表的特点

(1)不需要连续的内存空间
(2)有指针引用
(3)三种常见的链表结构:单链表、双链表、循环链表、(跳表:不常见但是功能强大,用到的地方也很多,比如redis,可以了解一下)
单链表: 第一个结点和最后一个结点分别为头结点和尾结点。头结点用来记录链表的基地址,有了它,我们就可以遍历得到整条链表。而尾结点的特殊地方是:指针不是指向下一个结点,而是指向一个空地址NULL,表示这是链表上的最后一个结点。
双向链表: 单向链表只有一个方向,结点只有一个后继指针next指向后面的结点。双向链表,顾名思义,它支持两个方向,每个结点不止有一个后继指针next指向后面的结点,还有一个前驱指针prev指向前面的结点。双向链表需要额外的两个空间来存储后继结点和前驱结点的地址。缺点:如果存储同样多的数据,双向链表要比单链表占用更多的内存空间。优点:可以支持双向遍历,操作灵活(特别是对于范围查询有明显的优势、大于、小于)。实际应用:如 B+Tree(MySQL索引的叶子节点,采用的就是双向链表结构)
循环链表: 循环链表就是一种特殊的单链表。实际上,循环链表与单链表的唯一区别就是尾节点。单链表的尾节点指针指向空地址,表示这就是最后的结点了,而循环链表的尾结点指针是指向链表的头结点,形成一个环一样首尾相连的链表,所以"循环"链表。(约瑟夫问题)

3、为何要使用链表

稀疏数组:一般是针对多维数组
 1 2  4 -1
-1 3  5 -1
-1 1 -1 -1
a[3][4]:这是一个二维数组,-1表示存储的数据为空,已开空间大小3*4=12,稀疏数组就是真正存的数据远远小于我们开的空间,为了节省空间,往往会用链表代替。

4、数组与链表的区别

重要区别:
(1)数组简单易用,在实现上使用的是连续的内存空间,可以借助CPU的缓存机制(缓存行、缓存局部性),预读数组中的数据,所以访问效率更高。
(2)链表在内存中并不是连续存储,所以对CPU缓存不友好,没办法有效预读。
(3)数组的缺点就是大小固定,一经声明就要占用整块连续内存空间。如果声明的数组过大,系统可能没有足够的连续内存空间分配给它,导致"内存不足(Out Of Memory)"。如果声明的数组过小,则可能出现不够用的情况。
(4)动态扩容:数组需再申请一个更大的内存空间,把原数组拷贝过去,非常费时。链表本身没有大小限制,天然支持动态扩容。(但是链表不断的扩容会把内存撑爆,使用时需要注意)

5、链表的增删查

单向链表结构:头结点,指针(指向下一节点),value(存储的值),size已存储值的数量
    public class MyLinkedList {private int size;ListNode head;class ListNode { //定义链表结构int value;ListNode next;ListNode(int value) { //构造函数,用于构造一个结点this.value = value;this.next = null;head = null;}}}

5.1、在头部插入链表

    private void insertHead(int data) {//时间复杂度O(1)ListNode newData = new ListNode(data);//构造一个结点newData.next = head; //栈内存的引用head = newData;size++;}

5.2、在中间插入链表

 private void insertNth(int data, int position) {//插入链表的中间,假设定义在第N个插入,O(n)if (position == 0){//这里表示插入在头部insertHead(data);} else {ListNode newData = new ListNode(data);ListNode curr = head;for (int i=0; i< position; i++){curr = curr.next;//一直往后遍历,找到要插入的位置,c/c++的 p=p->next;}//确保链表不会断裂丢失数据newData.next = curr.next;//先将新加的结点指向后面,保证不断链curr.next = newData;//把当前的点指向新加的点}size++;}

5.3、删除头节点

    private void deleteHead(int data) {//O(1)head = head.next;size--;}

5.4、删除中间节点

   private void deleteNth(int data, int position) {//O(1)if (position == 0){deleteHead(data);} else {ListNode curr = head;for (int i=0; i< position; i++){curr = curr.next;}curr.next = curr.next.next;//curr.next 表示的是删除的点}size--;}

5.5、查询某个值

    public void find(int data){//O(n)ListNode cur = head;while(cur != null){//判断不是尾结点if(cur.value == data) break;//找到后退出循环cur = cur.next;//遍历下一个结点}}

6、链表的应用

6.1 如何设计一个LRU缓存算法?

LRU(Least Recently Used:最近最少使用,它主要思想是当缓存空间占满时,移除最近最少使用的缓存对象)
    /*** 1、先判断链表中是否已存在该data,如果已存在则抛弃旧的值,然后在head插入新的值* 2、如果不存在改data,则直接在head插入该data,保证head为最新访问的值* 这里实现的是简单的lru,深层次的lru可使用哈希表+双向链表实现(可参考力扣的题目)* @param data*/private void lru (int data) {ListNode newData = new ListNode(data);ListNode curr = head;while (curr.next != null) {if (curr.value == data){//删除该结点curr.next = curr.next.next;break;}curr = curr.next;}//插入链表头部head = newData.next;}

6.2 约瑟夫问题

读者可以先思考此问题的实现,该问题的求解过程小编会在另一篇博文解答,敬请期待!!

http://www.tj-hxxt.cn/news/48794.html

相关文章:

  • 广州网络兼职网站建设百度网盘下载电脑版官方下载
  • nas 可以做网站吗天津seo推广软件
  • 3gb2c.com是什么网站郑州seo优化大师
  • 外贸建站效果百度网站域名注册
  • 在云服务器上搭建网站内容营销的4个主要方式
  • 崇信县门户网站首页百度推广营销页
  • 微信网站设计运营网络营销的工具有哪些
  • 如何做幼儿园网站设计北京十大营销策划公司
  • 上海工作室宁德seo公司
  • 深圳专业建网站公司专业seo网络营销公司
  • 网站建设开发计入二级科目明细免费注册域名网站
  • python做网站服务器操作系统搜索引擎大全排名
  • 一级水蜜桃宁波seo搜索引擎优化
  • 滕州外贸网站建设seo全网营销
  • 石家庄网站建设案例现在阳性最新情况
  • 新密做网站推广常用的网络推广手段有哪些
  • 公司网站开发费用好的竞价推广托管
  • 网站错误提示页设计创新驱动发展战略
  • 网站搜索怎么做的电商运营公司
  • 为博彩做网站日入两万广告推广渠道有哪些
  • 建设眼镜网站风格免费广告推广软件
  • 怎么免费建立自己的网站步骤电脑版百度入口
  • 昆明网站建设询力鼎科技著名的营销成功的案例
  • 如何做网站直播入口我要恢复百度
  • 望牛墩镇仿做网站重庆seo关键词排名
  • html5 图片网站昆明新闻头条最新消息
  • 德阳北京网站建设网络推广方案书模板
  • 个人做房产网站国际新闻头条今日国际大事
  • dede页码的调用 网站seo是什么及作用
  • 公众号关注武汉seo搜索优化