数据结构与算法-链表(含经典面试题)

news2024/11/26 6:12:08

     一 面试经典:

        1. 如何设计一个LRU缓存淘汰算法?基础

        思想:新加的点来了, 首先去链表里面遍历,如果找到了。删掉 然后插入到头部。头部就是最新的吧如果不在原来的链表里:如果有空间就插入头部。LRU有内存限制的,如果没有空间了怎么办? 删除最后一个,完成了这个算法!

( 最近使用,只需要维护一个有序的单链表就可以了。有序的指的就是加入的时间排序 )

        2. 约瑟夫问题  (对手娟,丢到谁谁淘汰,只留最后一个人)

       二 什么是链表?

        1.链表的定义

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

        2.特点
                (1)不需要连续的内存空间。
                (2)有指针引用
                (3)三种最常见的链表结构:单链表、双向链表和循环链表

        单向链表说明:

        从单链表图中,可以发现,有两个结点是比较特殊的,它们分别是第一个结点和最后一个结点。我们一般把第一个结点叫作头结点,把最后一个结点叫作尾结点。
其中,头结点用来记录链表的基地址。有了它,我们就可以遍历得到整条链表。而尾结点特殊的地方是:指针不是指向下一个结点,而是指向一个空地址NULL,表示这是链表上最后一个结点。while(p.next != null){} head 自己记录的

          循环链表说明:

        循环链表是一种特殊的单链表。实际上,循环链表也很简单。它跟单链表唯一的区别就在尾结点。我们知道,单链表的尾结点指针指向空地址,表示这就是最后的结点了。而循环链表的尾结点指针是指向链表的头结点。从我画的循环链表图中,你应该可以看出来,它像一个环一样首尾相连,所以叫作“循环”链表。

      三 代码实现单链表和双向链表

package list;

/**
 * @author:Kevin
 * @create: 2023-08-14 10:45
 * @Description:        单向列表
 */

public class MyLinkedList {

    private ListNode head;
    private int size = 0;

    public void insertHead(int data){    //插入链表头部    O(1)
        ListNode newNode = new ListNode(data);

        newNode.next = head;
        head = newNode;

    }

    public void inertNth(int data,int postion){        //插入链表中间位置   O(n)
        if (postion == 0){
            insertHead(data);
        }else {
            ListNode cur = head;
            for (int i = 1;i<postion;i++){
                cur = cur.next;
            }
            ListNode listNode = new ListNode(data);

            listNode.next = cur.next;
            cur.next = listNode;
        }

    }

    public void deleteHead(){   //O(1)

        head = head.next;

    }

    public void deleteNth(int position){    //O(n)

        if (position == 0){
            deleteHead();
        }else {
            ListNode cur = head;
            for (int i =1;i<position;i++){
                cur = cur.next;
            }
            cur.next=cur.next.next;
        }

    }

    public void print(){

        ListNode cur = head;
        while (cur!=null){
            System.out.println(cur.value);
            cur = cur.next;
        }

    }



}

class ListNode{

    int value;  //值
    ListNode next;  //指针

    ListNode(int value) {
        this.value = value;
        this.next = null;
    }
}

                双向链表

package list;

/**
 * 	双向列表
 */
public class DoubleLinkList {		// 双向链表

	private DNode head;		//头 
	private DNode tail;		// 尾
	
	DoubleLinkList(){
		head = null;
		tail = null;
	}
	
	public void inserHead(int data){
		DNode newNode = new DNode(data);
		if(head == null){
			tail = newNode;
		}else{
			head.pre = newNode;
			newNode.next = head;
		}
		head = newNode;
	}
	public void deleteHead(){
		if(head == null) return ;		//没有数据
		if(head.next == null){		//就一个点
			tail = null;
		}else{
			head.next.pre = null;	
		}
		head = head.next;
	}

	public void deleteKey(int data){
		DNode current = head;
		while (current.value != data) {
			if (current.next == null) {
				System.out.println("没找到节点");
				return ;
			}
			current = current.next;
		}
		if (current == head) {// 指向下个就表示删除第一个
			deleteHead();
		} else {
			current.pre.next = current.next;
			if(current == tail){		//删除的是尾部
				tail = current.pre;
				current.pre = null;
			}else{
				current.next.pre = current.pre;
			}
		}
	}
}

class DNode{
	
	int value;		//值
	DNode next;		//下一个的指针
	DNode pre;		//指向的是前一个指针

	DNode(int value){
		this.value = value;
		this.next = null;
		this.pre = null;
	}
}

     四 数组vs链表

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/875874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

理解 Go 中的切片:append 操作的深入分析(篇2)

理解 Go 语言中 slice 的性质对于编程非常有益。下面&#xff0c;我将通过代码示例来解释切片在不同函数之间传递并执行 append 操作时的具体表现。 本篇为第 2 篇&#xff0c;当切片的容量 cap 不够时 func main() {// slice1 当前长度为 3&#xff0c;容量大小也为 3slice1 :…

探索Python中的函数和类:构建模块化和面向对象的程序

文章目录 &#x1f340;引言&#x1f340;函数&#xff1a;模块化编程的基石&#x1f340;类&#xff1a;面向对象编程的基石&#x1f340;函数和类的结合&#xff1a;构建高效的程序&#x1f340;简单的文字冒险游戏 &#x1f340;引言 Python作为一种多范式的编程语言&#x…

web图书管理系统Servlet+JSP+javabean+MySQL图书商城图书馆 源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 web图书管理系统ServletJSPjavabeanMySQL 系统有1权限…

用于100GB+、TB级大型数据集构建【2】--计算包Xarray-主要数据类型

引言&#xff1a; Xarray是一个性能出众的张量操作库&#xff0c;通常用于多通道的时间序列信号处理&#xff08;比如传感器信号&#xff09;。通常&#xff0c;在处理此类数据时&#xff0c;我认为您经常使用numpy的np.ndarray。但是&#xff0c;由于np.ndarray是一个简单的矩…

[保研/考研机试] KY103 2的幂次方 上海交通大学复试上机题 C++实现

题目链接&#xff1a; KY103 2的幂次方 https://www.nowcoder.com/share/jump/437195121691999575955 描述 Every positive number can be presented by the exponential form.For example, 137 2^7 2^3 2^0。 Lets present a^b by the form a(b).Then 137 is present…

Linux设备树详解

Linux 设备树详解 Linux 操作系统早期是针对个人电脑设备而开发的操作系统&#xff0c;而个人电脑处理器产商较为单一&#xff08;例如只有 Intel&#xff0c;AMD&#xff09;同时个人电脑产商均使用 Intel 或 AMD 制造的处理器&#xff0c;业界形成了统一的总线/硬件接口标准…

稀疏感知图像和体数据恢复的系统对象研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

SpringCloud微服务之间如何进行用户信息传递(涉及:Gateway、OpenFeign组件)

目录 1、想达到的效果2、用户信息在微服务之间传递的两种途径3、用RuoYi-Cloud为例进行演示说明&#xff08;1&#xff09;网关将用户信息写在请求头中&#xff08;2&#xff09;业务微服务之间通过OpenFeign进行调用&#xff0c;并且将用户信息写在OpenFeign准备的请求头中&am…

02:STM32--EXTI外部中断

目录 一:中断 1:简历 2:AFIO 3:EXTI ​编辑 4:NVIC基本结构 5:使用步骤 二:中断的应用 A:对外式红外传感计数器 1:连接图​编辑 2:函数介绍 3:硬件介绍 4:计数代码 B;旋转编码计数器 1:连接图 2:硬件介绍 3:旋转编码器代码: 一:中断 1:简历 中断&#xff1a;在主程…

硬件产品经理:从入门到精通(新书发布)

目录 简介 新书 框架内容 相关课程 简介 在完成多款硬件产品从设计到推向市场的过程后。 笔者于2020年开始在产品领域平台输出硬件相关的内容。 在这个过程中经常会收到很多读者的留言&#xff0c;希望能推荐一些硬件相关的书籍或资料。 其实&#xff0c;笔者刚开始做硬…

电力能源管理系统在生物制药行业的应用

安科瑞 华楠 摘要&#xff1a;根据生物制品类企业的电力能源使用特点&#xff0c;制定了符合公司实际情况的能源管理系统&#xff0c;介绍了该系统的架构及其在企业的应用情况&#xff0c;提升了公司能源数据的实时监控能力&#xff0c;优化了公司能源分配&#xff0c;降低了公…

React Native Expo项目,复制文本到剪切板

装包&#xff1a; npx expo install expo-clipboard import * as Clipboard from expo-clipboardconst handleCopy async (text) > {await Clipboard.setStringAsync(text)Toast.show(复制成功, {duration: 3000,position: Toast.positions.CENTER,})} 参考链接&#xff1a…

接口自动化测试,Fiddler使用抓包辅助实战,一篇彻底打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、快捷设置&…

GaussDB数据库SQL系列-UNION UNION ALL

目录 一、前言 二、GaussDB UNION/UNION ALL 1、GaussDB UNION 操作符 2、语法定义 三、GaussDB实验示例 1、创建实验表 2、合并且除重(UNION) 3、合并不除重&#xff08;UNION ALL&#xff09; 4、合并带有WHERE子句SQL结果集&#xff08;UNION ALL&#xff09; 5、…

ansible的playbook剧本

playbook剧本 PlayBook1.playbooks 本身由以下各部分组成2.示例&#xff1a;3.运行playbook补充参数&#xff1a; 4.定义、引用变量5.指定远程主机sudo切换用户6.when条件判断7.迭代8.Templates 模块1.先准备一个以 .j2 为后缀的 template 模板文件&#xff0c;设置引用的变量2…

9.3.2.2网络原理(传输层TCP)

TCP全部细节参考RFC标准文档 一.TCP特点: 有连接,可靠传输,面向字节流,全双工. 二.TCP数据报: 1.端口号是传输层的重要概念. 2.TCP的报头是变长的(UDP是固定的8字节),大小存在4位首部长度中,用4个bit位(0~15)表示长度单位是4字节.(TCP报头最大长度是60字节,前面20字节是固定…

VR时代真的到来了?

业界对苹果的期待是&#xff0c;打造一台真正颠覆性的&#xff0c;给头显设备奠定发展逻辑底座的产品&#xff0c;而实际上&#xff0c;苹果只是发布了一台更强大的头显。 大众希望苹果回答的问题是“我为什么需要一台AR或者VR产品&#xff1f;”&#xff0c;但苹果回答的是“…

数据结构—图的应用

6.4图的应用 概念回顾—生成树 生成树&#xff1a;所有顶点均由边连接在一起&#xff0c;但不存在回路的图。 一个图可以有许多棵不同的生成树、含有n个顶点 n-1 条边的图不一定是生成树所有生成树具有以下共同特点 生成树的顶点个数与图的顶点个数相同&#xff1b;生成树是图的…

【正点原子STM32连载】第四章 APM32初体验摘自【正点原子】APM32F407最小系统板使用指南

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第四…

达梦数据库(dm8) Centos7 高可用集群

国产数据库-达梦 一、环境详情二、Centos7 参数优化&#xff08;所有节点&#xff09;三、创建用户&#xff08;所有节点&#xff09;四、开始安装&#xff08;所有节点&#xff09;五、服务注册启动 当前安装&#xff1a;在指定版本环境下 测试&#xff0c;仅供参考 官网描述&…