03-java实现循环链表
03java实现循环链表
一丶单向循环链表
- 就是为尾节点指向头结点
二丶单向循环链表的接口设计
- 比较单向链表,单向循环链表只需要修改添加节点,删除节点两个方法,也就是add和remove方法
三丶单向循环链表的实现
3.1添加节点
- 相比于单向链表,单向循环链表只需要特别关注插入头结点的情况即可
- 需要考虑的特殊情况是当链表的长度为0的时候的插入的情况
public void add(int index, E element) {
rangeCheckForAdd(index);
if (index == 0) {
Node<E> newFirst = new Node<>(element, first);
// 拿到最后一个节点
Node<E> last = (size == 0) ? newFirst : node(size - 1);
last.next = newFirst;
first = newFirst;
} else {
Node<E> prev = node(index - 1);
prev.next = new Node<>(element, prev.next);
}
size++;
}
3.2删除节点
- 如果删除的是头节点,删除后需让last指向新的头节点。
- 当只有一个节点并删除时, first指向null。
public E remove(int index) {
rangeCheck(index);
Node<E> node = first;
//删除头节点
if (index == 0) {
// 只有一个节点
if (size == 1) {
first = null;
} else {
Node<E> last = node(size - 1);
first = first.next;
last.next = first;
}
} else {
Node<E> prev = node(index - 1);
node = prev.next;
prev.next = node.next;
}
size--;
return node.element;
}
四、双向循环链表
五、双向循环链表接口设计
- 相较于双向链表,双向循环链表需要重写插入节点、删除节点两个方法。
六丶双向循环链表接的实现
6.1插入节点
- 需特殊处理添加第一个元素和添加到尾节点两种特殊情况。
public void add(int index, E element) {
rangeCheckForAdd(index);
// 如果 index == size, 说明添加的索引是最后位置
if (index == size) {
// 创建新节点, prev指向原链表的尾节点, next指向首节点
Node<E> node = new Node<>(last, element, first);
// 当原链表没有任何节点
if (size == 0) {
first = node;
last = node;
node.prev = node;
node.next = node;
}else {
// 原链表尾节点next指向node
last.next = node;
// 原链表头结点prev指向node
first.prev = node;
// last指向新的尾节点
last = node;
}
}else {
// 添加新节点后的下一个节点
Node<E> next = node(index);
// 添加新节点后的上一个节点
Node<E> prev = next.prev;
// 创建新节点, 新节点的上一个节点时prev, 新节点的下一个节点是next
Node<E> node = new Node<>(prev, element, next);
// next的上一个节点是新节点
next.prev = node;
// prev的下一个节点是新节点
prev.next = node;
// 当next == first时, 说明新添加节点的索引是0
if (next == first) {
first = node;
}
}
size++;
}
6.2删除节点
- 删除节点,就是在环上去掉某一个节点,然后根据删除的节点是首节点或者尾节点来处理first和last。
- 需要特殊处理只有一个节点的删除操作。
public E remove(int index) {
// 需要删除的节点
Node<E> node = node(index);
if (size == 1) {
first = null;
last = null;
}else {
// 删除节点的前一个节点
Node<E> prev = node.prev;
// 删除节点的后一个节点
Node<E> next = node.next;
next.prev = prev;
prev.next = next;
// 如果node == first, 说明删除的是第一个节点
if (node == first) {
first = next;
}
// 如果next == last, 说明删除的是最后一个节点
if (next == last) {
last = prev;
}
}
size--;
return node.element;
}
03-java实现循环链表的更多相关文章
- java与数据结构(3)---java实现循环链表
循环链表:将单链表中尾结点的指针由空指针改为指向头结点,就使整个单链表形成一个环,这种首尾相接的单链表称为单链表循环表,即循环链表. 循环链表与单链表最重要的区别是:尾结点的指针,不再是p->n ...
- java实现循环链表的增删功能
java实现循环链表的增删功能,完整代码 package songyan.test.demo; public class Demo { // java 实现循环链表 public static voi ...
- Java-Runoob-高级教程-实例-方法:03. Java 实例 – 汉诺塔算法-un
ylbtech-Java-Runoob-高级教程-实例-方法:03. Java 实例 – 汉诺塔算法 1.返回顶部 1. Java 实例 - 汉诺塔算法 Java 实例 汉诺塔(又称河内塔)问题是源 ...
- Java-Runoob-高级教程-实例-时间处理:03. Java 实例 - 获取年份、月份等
ylbtech-Java-Runoob-高级教程-实例-时间处理:03. Java 实例 - 获取年份.月份等 1.返回顶部 1. Java 实例 - 获取年份.月份等 Java 实例 以下实例演示 ...
- Java-Runoob-高级教程-实例-数组:03. Java 实例 – 获取数组长度-*
ylbtech-Java-Runoob-高级教程-实例-数组:03. Java 实例 – 获取数组长度 1.返回顶部 Java 实例 - 获取数组长度 Java 实例 本文我们将为大家介绍如何使用数 ...
- Java-Runoob-高级教程-实例-字符串:03. Java 实例 - 删除字符串中的一个字符
ylbtech-Java-Runoob-高级教程-实例-字符串:03. Java 实例 - 删除字符串中的一个字符 1.返回顶部 1. Java 实例 - 删除字符串中的一个字符 Java 实例 以 ...
- [03]java中的方法以及控制语句
00 Java中的语句块 语句块(有时叫做复合语句),是用花括号扩起的任意数量的简单Java语句.块确定了局部变量的作用域.块中的程序代码,作为一个整体,是要被一起执行的.块可以被嵌套在另一个块中,但 ...
- 033 01 Android 零基础入门 01 Java基础语法 03 Java运算符 13 运算符和表达式知识点总结
033 01 Android 零基础入门 01 Java基础语法 03 Java运算符 13 运算符和表达式知识点总结 本文知识点:运算符和表达式知识点总结 前面学习的几篇文都是运算符和表达式相关的知 ...
- 032 01 Android 零基础入门 01 Java基础语法 03 Java运算符 12 运算符和if-else条件语句的综合案例——闰年问题
032 01 Android 零基础入门 01 Java基础语法 03 Java运算符 12 运算符和if-else条件语句的综合案例--闰年问题 本文知识点:运算符和if-else条件语句的综合案例 ...
- 031 01 Android 零基础入门 01 Java基础语法 03 Java运算符 11 运算符的优先级
031 01 Android 零基础入门 01 Java基础语法 03 Java运算符 11 运算符的优先级 本文知识点:Java中运算符的优先级 运算符的优先级问题 前面学习了很多的运算符,如果这些 ...
随机推荐
- CRM开发系列
CRM,客户关系管理系统(Customer Relationship Management).企业用CRM技术来管理与客户之间的关系,以求提升企业成功的管理方式,其目的是协助企业管理销售循环:新客户的 ...
- Swift开发笔记
Swift开发笔记(一) 刚开始接触XCode时,整个操作逻辑与Android Studio.Visual Studio等是完全不同的,因此本文围绕IOS中控件的设置.事件的注册来简单的了解IOS开发 ...
- 03-Python控制语句
一.简介 通过一些语句来改变程序的执行顺序,这些语句被叫做控制语句,在python主要有if.for.while三种控制流语句. 二.if语句 用来检测一个条件是否成立,如果为真,则执行该语句(一般为 ...
- md5加密密码
using System.Security.Cryptography; public string GetStrMd5(string ConvertString) { MD5CryptoService ...
- Serverless的概念&定义-无服务计算详解
过去几年间,Serverless 发展迅猛,与其相伴的还有从小程序.移动端等到前后端一体化的演进与实践,也正因如此,从云计算到前端,众多开发者都极为关注 Serverless到底是什么? 在国内,Se ...
- 如何将你写的脚本程序打包成一个exe可执行程序
编写的程序打包成一个exe文件,随时可以双击执行,想想是不是很酷.接下来我们一起看一下如何将自己编写的程序打包为一个exe的可执行程序. 将程序打包成exe的好处 除了满足自己的成就感以外, ...
- React js ReactDOM.render 语句后面不能加分号
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- java中int相除取小数点后两位或限定位数
java 两个整数相除保留两位小数: http://blog.sina.com.cn/s/blog_624d755d0101cvuq.html java中,当两个整数相除时,由于小数点以后的数字会被截 ...
- 你真的清楚DateTime in C#吗?
DateTime,就是一个世界的大融合. 日期和时间,在我们开发中非常重要.DateTime在C#中,专门用来表达和处理日期和时间. 本文算是多年使用DateTime的一个总结,包括DateTim ...
- Ubuntu14.04 安装VMware tools
Ubuntu14.04 安装VMware tools 方法一: 1. 在VMware 11(个人的测试环境为vm 11版本)下安装Ubuntu镜像:ubuntu-14.04.1-desktop-amd ...