双向链表的模拟实现 —— LinkedList

news/2024/12/12 12:48:05/

MyLinkedList类

java">public class MyLinkedList {// 定义节点类static class Node {int val;Node prev;Node next;public Node() {}public Node(int val) {this.val = val;}}// 定义头节点private Node head;// 定义尾结点private Node tail;// 头插public void headInsert(int val) {// 申请节点Node node = new Node(val);// 判空if (head == null) {// head 和 tail 都指向 nodehead = node;tail = node;return;}// head 不为空,则进行头插node.next = head;head.prev = node;// 重置头节点head = node;}// 尾插public void tailInsert(int val) {// 申请节点Node node = new Node(val);// 判空if (head == null) {head = node;tail = node;return;}// 非空情况下进行尾插tail.next = node;node.prev = tail;// 重置尾结点tail = node;}// 在 index 处插入元素public void randomInsert(int index, int val) {// 判空if (head == null) return;// 下标判断if (index < 0 || index > size()) {throw new IndexOfLinkedListException("下标 index :" + index + " 出现异常!");}// 头插if (index == 1) {headInsert(val);return;}// 尾插if (index == size()) {tailInsert(val);return;}// 找到要插入的位置Node cur = head;Node node = new Node(val);for (int i = 0; i < index; i++) {cur = cur.next;}// 进行插入cur.prev.next = node;node.next = cur;node.prev = cur.prev;cur.prev = node;}// 删除与 val 相等的元素节点public void remove(int val) {// 判空if (head == null) return;Node cur = head;while (cur != null) {// 值相等,进行删除if (cur.val == val) {// 头节点的情况if (cur == head) {head = head.next;head.prev = null;break;}// 尾结点的情况if (cur == tail) {tail = tail.prev;tail.next = null;break;}// 中间节点删除cur.prev.next = cur.next;cur.next.prev = cur.prev;}cur = cur.next;}}// 删除 index 处的元素public void removeOfIndex(int index) {// 判空if (head == null) return;// 下标判断if (index < 0 || index > size()) {throw new IndexOfLinkedListException("下标 index :" + index + " 出现异常!");}// 头删if (index == 1) {head = head.next;head.prev = null;return;}// 尾删if (index == size()) {tail = tail.prev;tail.next = null;return;}// 找到要删除的位置Node cur = head;for (int i = 1; i < index; i++) {cur = cur.next;}// 进行删除操作cur.prev.next = cur.next;cur.next.prev = cur.prev;}// 删除所有与 val 相等的节点public void removeAllVal(int val) {// 判空if (head == null) return;// 判断 val 值是否在链表中出现if (!contains(val)) return;// 从头节点开发判断Node cur = head;while (cur != null) {// 相等则进行删除if (cur.val == val) {// 是头节点的情况if (head == cur) {// head 走到下一个节点处head = head.next;head.prev = null;} else if (tail == cur) {// tail 走到上一个节点处tail = tail.prev;tail.next = null;} else {// 中间节点,让删除节点的前一个节点和后一个节点进行连接cur.next.prev = cur.prev;cur.prev.next = cur.next;}}// 注意,cur 无论是否删除了当前节点,都应该要走到下一步cur = cur.next;}}// 查找 val 第一次出现的下标public int indexOf(int val) {// 判空if (head == null) return -1;Node cur = head;for (int i = 1; i < size() + 1; i++) {// 找到了if (cur.val == val) {return i;}cur = cur.next;}// 没找到return -1;}// 查找 val 最后一次出现的下标public int lastOfIndex(int val) {// 判空if (head == null) return -1;int index = -1;Node cur = tail;for (int i = size(); i > 0; i--) {// 找到了if (cur.val == val) {index = i;}cur = cur.prev;}// 没找到return index;}// 判断 val 是否在链表中public boolean contains(int val) {// 判空if (head == null) return false;Node cur = head;while (cur != null) {// 找到了if (cur.val == val) {return true;}cur = cur.next;}// 没找到return false;}// 获取元素个数public int size() {Node cur = head;// 获取链表中的元素个数int count = 0;while (cur != null) {count++;cur = cur.next;}return count;}// 打印链表public void display() {Node cur = head;// 进行打印操作while (cur != null) {System.out.print(cur.val + " ");cur = cur.next;}// 换行System.out.println();}// 清空链表public void clear() {Node cur = head;// 把每个节点都置为 nullwhile (cur != null) {Node tmp = cur.next;cur.next = null;cur.prev = null;cur = tmp;}// 头节点和尾结点置空head = null;tail = null;}
}

 

IndexOfLinkedListException类

java">public class IndexOfLinkedListException extends RuntimeException {public IndexOfLinkedListException() {}public IndexOfLinkedListException(String message) {super(message);}
}

 

 Test类

java">public class Test {public static void main(String[] args) {MyLinkedList linkedList = new MyLinkedList();// 头插linkedList.headInsert(1);linkedList.headInsert(2);linkedList.headInsert(3);// 打印链表linkedList.display();// 获取长度System.out.println(linkedList.size());// 尾插linkedList.tailInsert(4);linkedList.tailInsert(5);linkedList.tailInsert(6);linkedList.display();System.out.println(linkedList.size());// 任意位置插入linkedList.randomInsert(1, 7);linkedList.randomInsert(1, 7);linkedList.randomInsert(1, 7);linkedList.randomInsert(8, 8);linkedList.display();linkedList.randomInsert(8, 7);linkedList.display();linkedList.randomInsert(8, 8);linkedList.display();System.out.println(linkedList.size());linkedList.randomInsert(2, 111);linkedList.randomInsert(3, 111);linkedList.display();System.out.println(linkedList.size());// 删除所有和 val 相等的节点linkedList.removeAllVal(7);linkedList.display();System.out.println(linkedList.size());// 删除链表中第一个 val 相等的节点linkedList.remove(111);linkedList.remove(6);linkedList.remove(3);linkedList.display();System.out.println(linkedList.size());// 删除 index 处的节点linkedList.removeOfIndex(1);linkedList.removeOfIndex(6);linkedList.removeOfIndex(2);linkedList.display();System.out.println(linkedList.size());// 找到 val 第一次出现的位置System.out.println(linkedList.indexOf(2));System.out.println(linkedList.indexOf(8));// 找到val 最后一次出现的位置System.out.println(linkedList.lastOfIndex(2));System.out.println(linkedList.lastOfIndex(8));// 清空链表linkedList.clear();System.out.println(linkedList.size());}
}


http://www.ppmy.cn/news/1554497.html

相关文章

Linux C语言操作sqlite3数据库

一、环境配置 1、下载源码&#xff1a;sqlite-autoconf-3470200.tar.gz 2、解压&#xff0c;cd到源码主目录 3、配置参数 ./configure --prefix/usr/local/ 如果是交叉编译环境 ./configure CC/opt/rk3288/gcc-linaro/bin/arm-linux-gnueabihf-gcc --hostarm-linux --pre…

《知识拓展 · 统一建模语言UML》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

【jvm】垃圾回收的优点和原理

目录 1. 说明2. 优点3. 原理3.1 发现无用对象3.2 回收无用对象所占用的内存 4. 回收算法4.1 标记-清除算法4.2 复制算法4.3 标记-整理算法4.4 分代收集算法 1. 说明 1.JVM&#xff08;Java虚拟机&#xff09;垃圾回收是Java语言的一大特性&#xff0c;它自动管理内存&#xff…

【Linux】git操作

git操作 gitee为例 新建仓库并拉取到本地 在gitee上新建仓库后 我们点击这个橙色的克隆、下载 选择HTTPS的链接进行复制 我们创建一个test目录并cd进去 我们就可以把远端仓库拉取下来&#xff1a; git clone后面带上刚才复制的链接 现在test目录下就有我们拉取下来的仓库…

如何绕过IP禁令

网站、游戏和应用程序可以屏蔽特定IP地址&#xff0c;从而阻止使用该IP地址的任何人访问其服务。这称为IP禁令。管理员可以出于多种原因&#xff08;例如发出过多请求或可疑活动&#xff09;屏蔽IP地址。但是&#xff0c;这些禁令会使收集数据或访问在线内容变得更加困难。 一…

保姆级教学 uniapp绘制二维码海报并保存至相册,真机正常展示图片二维码

一、获取二维码 uni.request({url: https://api.weixin.qq.com/wxa/getwxacode?access_token${getStorage("token")},responseType: "arraybuffer",method: "POST",data: {path: "/pages/index/index"},success(res) {// 转换为 Uint…

《人工智能安全:挑战与破局之路》

《人工智能安全&#xff1a;挑战与破局之路》 一、人工智能安全现状二、人工智能安全面临的挑战&#xff08;一&#xff09;技术层面的挑战&#xff08;二&#xff09;伦理与社会层面的挑战 四、人工智能安全未来发展趋势&#xff08;一&#xff09;技术创新引领发展&#xff0…

【Redis源码】网络模型

Redis源码解析网络模型 基于Redis7源码的网络模型解析 前置准备 源码地址&#xff1a;https://github.com/redis/redis Ide&#xff1a;Clion 网络模型 流程节点下方是源码中对应的方法 总结点 Redis 的网络是IO多路复用指令还是单线程串行 扩展的线程池&#xff0c;协助主…