算法 数据结构 双向环形链表 手撸环形链表 环形链表实现容器 环形链表添加修改删除获取大小 环形链表实现自定义容器 手撸容器 双向环形哨兵链表 数据结构(六)

 1. 环形链表:

                 

2. 建议先不要看我写得自己先实现下,只将Node内部类复制自己命名得容器内,

    实现方法:

                     a. add方法(添加到头部,尾部添加,指定位置添加)

                     b. get方法(获取首部,获取尾部,获取指定位置)

                     c. remove方法(删除首部,删除尾部,删除指定位置)

                     d. size方法(手动维护一个size变量,实现0(1)复杂度 )

                     e. 迭代器(实现迭代器,能够循环遍历)

     手动实现之后(每个功能只实现一种也可以),再回头参照,思考下即可!  

package com.nami.algorithm.study.day05;import java.io.Serializable;
import java.util.Iterator;
import java.util.function.Consumer;/*** 环形双向哨兵链表* 非线程安全* beyond u self and trust u self.** @Author: lbc* @Date: 2023-09-01 9:07* @email: 594599620@qq.com* @Description: keep coding*/
public class RingLinkedList<E> implements Serializable, Iterable<E>, Cloneable {/*** 容器已添加的元素*/private int size = 1;/*** 哨兵节点*/private Node sentinel = new Node(null, "-1", null);/*** 初始化哨兵*/public RingLinkedList() {this.sentinel.prev = this.sentinel;this.sentinel.next = this.sentinel;}/*** 向链表添加数据** @param element 添加的元素*/public void addFirst(E element) {Node first = this.sentinel;Node next = first.next;Node node = new Node<>(first, element, next);first.next = node;next.prev = node;++this.size;}/*** 向链表尾部添加数据** @param element*/public void addLast(E element) {Node last = this.sentinel.prev;Node node = new Node<>(last, element, sentinel);last.next = node;sentinel.prev = node;++this.size;}/*** 获取容器指定位置的值** @param index* @return*/public E get(int index) {if (index > size - 1) {throw new IndexOutOfBoundsException("元素不存在");}Node next = sentinel.next;for (int i = 0; i < index; next = next.next, i++) {}if (sentinel == next) {throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", index));}return (E) next.value;}/*** 获取指定位置节点node** @param index* @return*/private Node getNode(int index) {Node next = sentinel.next;for (int i = 0; i < index; next = next.next, i++) {}return next;}/*** 向元素指定节点添加值** @param index* @param e*/public void add(int index, E e) {if (index > size - 1) {throw new IndexOutOfBoundsException("元素不存在");}Node node = getNode(index);Node prev = node.prev;Node node1 = new Node(prev, e, node);node.prev = node1;prev.next = node1;++this.size;}/*** 移除容器内第一个元素*/public void removeFirst() {Node node = getNode(0);if (sentinel == node) {throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", 0));}Node prev = node.prev;Node next = node.next;prev.next = next;next.prev = prev;--this.size;}/*** 删除第一个元素*/public void removeFirst0() {Node removed = this.sentinel.next;if (removed == this.sentinel) {throw new IndexOutOfBoundsException("容器内已无元素");}Node next = removed.next;this.sentinel.next = next;next.prev = this.sentinel;}/*** 移除容器内指定位置元素** @param index*/public void remove(int index) {if (index > size - 1) {throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", index));}Node node = getNode(index);if (sentinel == node) {throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", 0));}Node prev = node.prev;Node next = node.next;prev.next = next;next.prev = prev;--this.size;}/*** 删除最后一个节点*/public void removeLast() {Node prev = this.sentinel.prev;if (prev == this.sentinel) {return;}Node next = prev.next;Node prev0 = prev.prev;prev0.next = next;next.prev = prev0;--this.size;}/*** 获取容器大小** @return*/public int size() {return this.size - 1;}/*** 迭代器遍历** @return*/@Overridepublic Iterator iterator() {return new NodeIterator();}/*** 匿名内部类* 内部类使用到了外部类的成员变量时,不能使用static修饰*/private class NodeIterator implements Iterator {Node node = sentinel.next;@Overridepublic boolean hasNext() {return node != sentinel;}@Overridepublic Object next() {Object value = node.value;node = node.next;return value;}}/*** while实现** @param consumer*/public void forEach(Consumer consumer) {Node firstNode = this.sentinel.next;while (firstNode != sentinel) {consumer.accept(firstNode.value);firstNode = firstNode.next;}}/*** Node类型 节点对象* 二者为组合关系,所以 由外部类变为内部类,对外隐藏实现细节*/private static class Node<E> {/*** 上一个节点*/private Node<E> prev;/*** 值*/private E value;/*** 下一个节点*/private Node<E> next;public Node(Node<E> prev, E value, Node<E> next) {this.prev = prev;this.value = value;this.next = next;}}}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于costas环的载波同步系统matlab性能仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................................................................ I_Dataroun…

Word转为PDF后图片模糊怎么办?Word转为PDF的技巧介绍

将Word文档转为PDF是我们日常办公和文档处理中常见的需求。PDF格式的优势在于跨平台兼容性、保留原始格式、文档保护以及方便共享和分发等方面。本文将探讨Word转为PDF后图片模糊怎么办?Word转为PDF的技巧有哪些?通过这些问题的答案&#xff0c;可以帮助您更好的利用文件转换…

AJAX学习笔记5同步与异步理解

AJAX学习笔记4解决乱码问题_biubiubiu0706的博客-CSDN博客 示例 前端代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>演示AJAX同步和异步</title> </head> <body> <script…

Nginx跨域问题的解决方法

项目场景&#xff1a; Web前端开发经常会遇到跨域访问&#xff0c;如果没有办法让后台开放访问域&#xff0c;调用接口就会被浏览器拦截。解决跨域问题的方案&#xff0c;可以搭建一个后台服务做中间转发&#xff0c;也可以用nginxhttps://so.csdn.net/so/search?qnginx转发。…

【业务功能篇96】微服务-springcloud-springboot-认证服务-登录注册功能-Auth2.0-分布式session

5.登录功能 通过最基础的登录操作来完成登录处理 登录页面处理 认证服务的处理 /*** 注册的方法* return*/PostMapping("/login")public String login(LoginVo loginVo , RedirectAttributes redirectAttributes){R r memberFeginService.login(loginVo);if(r.getC…

手写Mybatis:第10章-使用策略模式,调用参数处理器

文章目录 一、目标&#xff1a;参数处理器二、设计&#xff1a;参数处理器三、实现&#xff1a;参数处理器3.1 工程结构3.2 参数处理器关系图3.3 入参数校准3.4 参数策略处理器3.4.1 JDBC枚举类型修改3.4.2 类型处理器接口3.4.3 模板模式&#xff1a;类型处理器抽象基类3.4.4 类…

C#FreeSql分库分表

using FreeSql; using FreeSql.DataAnnotations;namespace FreeSqlMaster {internal class Program{static IFreeSql freeSql null;static void Main(string[] args){// 读写分离// FreeSql 实现了第3种方案&#xff0c;支持一个【主库】多个【从库】&#xff0c;【从库】的查…

在OpenStack私有云上安装配置虚拟机

文章目录 零、学习目标一、登录大数据实训云二、创建网络三、创建路由四、添加接口五、创建端口六、添加安全组规则七、创建实例&#xff08;一&#xff09;实例规划&#xff08;二&#xff09;创建实例 - ied&#xff08;三&#xff09;创建实例 - master、slave1与slave2&…

字节二面:如果高性能渲染十万条数据?

前言 最近博主在字节面试中遇到这样一个面试题&#xff0c;这个问题也是前端面试的高频问题&#xff0c;作为一名前端开发工程师&#xff0c;我们虽然可能很少会遇到后端返回十万条数据的情况&#xff0c;但是了解掌握如何处理这种情况&#xff0c;能让你对前端性能优化有更深的…

Ubuntu tmux 默认安装 快捷键

安装 sudo apt install tmux 启动tmux tmux 注意下方已显示[0] 0:bash 左右分屏 依次输入两组快捷键&#xff1a;Ctrlb, Shift5 即:% 上下分屏 依次输入两组快捷键&#xff1a;Ctrlb, Shift 即:" 切换窗口&#xff08;注意&#xff1a;鼠标点击没有切换效果&#x…

华为OD机试-机器人走迷宫

题目描述 机器人走一个迷宫,给出迷宫的x和y(x*y的迷宫)并且迷宫中有障碍物,输入k表示障碍物有k个,并且会将障碍物的坐标挨个输入. 机器人从0,0的位置走到x,y的位置并且只能向x,y增加的方向走,不能回退. 如代码类注释展示的样子,#表示可以走的方格,0代表障碍,机器人从0,0的位置…

opencv-4.5.2-android-sdk.zip安装教程

opencv-4.5.2-android-sdk.zip&#xff1a; 下载链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;s0p2 导入模块的方法: ①、导入模块 ②、定位到sdk目录 点击ok就行&#xff0c;就导入成功了。导入成功后会多出一个可展开的opencv文件夹(自己命名的),一定要能展…