热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【数据结构】【线性表】链表

1引言链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的。

1 引言

链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的。
在这里插入图片描述


2 接口

/**
* @Description: 线性表接口
* @Auther: zhurongsheng
* @Date: 2020/4/22 23:26
*/

public interface ZrsList<E> {
/**
* 元素数量
*/

int size();
/**
* 是否为空
*/

boolean isEmpty();
/**
* 是否包含
*/

boolean contains(E element);
/**
* 添加元素
*/

void add(E element);
/**
* 返回index位置对应的元素
*/

E get(int index);
/**
* 设置index位置的元素,返回原来的元素
*/

E set(int index, E element);
/**
* 在index位置添加元素
*/

void add(int index, E element);
/**
* 删除index对应的元素
*/

E remove(int index);
/**
* 查看元素的位置
*/

int indexOf(E element);
/**
* 清除所有元素
*/

void clear();
}

3 实现类

/**
* @Description:
* @Auther: zhurongsheng
* @Date: 2020/4/25 13:55
*/

public class ZrsLinkedList<E> implements ZrsList<E> {
private int size;
private Node<E> first;
private Node<E> last;
public ZrsLinkedList() {
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public boolean contains(E element) {
return false;
}
@Override
public void add(E element) {
Node<E> lastNode = last;
Node<E> newNode = new Node<>(element, null, lastNode);
last = newNode;
if (first == null)
first = newNode;
else
lastNode.next = newNode;
size++;
}
@Override
public E get(int index) {
rangeCheck(index);
return node(index).element;
}
private void rangeCheck(int index) {
if (index >= 0 && index <= size - 1) {
return;
}
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index) {
if (index >= 0 && index <= size) {
return;
}
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: " + index + ", Size: " + size;
}
@Override
public E set(int index, E element) {
rangeCheck(index);
Node<E> node = node(index);
E oldValue = node.element;
node.element = element;
return oldValue;
}
@Override
public void add(int index, E element) {
rangeCheckForAdd(index);
if (index == size) {
add(element);
} else {
Node<E> node = node(index);
Node<E> prevNode = node.prev;
Node<E> newNode = new Node<>(element, node, prevNode);
prevNode.next = newNode;
node.prev = newNode;
size++;
}
}
@Override
public E remove(int index) {
rangeCheck(index);
Node<E> node = node(index);
E oldVal = node.element;
Node<E> nextNode = node.next;
Node<E> prevNode = node.prev;
if (prevNode == null) {
first = nextNode;
} else {
prevNode.next = nextNode;
node.prev = null;
}
if (nextNode == null) {
last = prevNode;
} else {
nextNode.prev = prevNode;
node.next = null;
}
node.element = null;
size--;
return oldVal;
}
@Override
public int
indexOf(E element) {
int index = 0;
if (element == null) {
for (Node<E> node = first; node != null; node = node.next) {
if (node.element == null) return index;
index++;
}
} else {
for (Node<E> node = first; node != null; node = node.next) {
if (node.element.equals(element)) return index;
index++;
}
}
return -1;
}
private Node<E> node(int index) {
if (index < size / 2) {
Node<E> x = first;
for (int i = 0; i < index; i++) {
x = x.next;
}
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--) {
x = x.prev;
}
return x;
}
}
@Override
public void clear() {
for (Node<E> node = first; node != null; ) {
Node<E> next = node.next;
node.element = null;
node.next = null;
node.prev = null;
node = next;
}
first = null;
last = null;
size = 0;
}
private static class Node<E> {
private E element;
Node<E> next;
Node<E> prev;
private Node(E element, Node<E> next, Node<E> prev) {
this.element = element;
this.next = next;
this.prev = prev;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
int index = 0;
for (Node<E> node = first; node != null; node = node.next) {
if (index == 0) {
sb.append(node.element);
} else {
sb.append(", ").append(node.element);
}
index++;
}
sb.append("]");
return sb.toString();
}
}

4 测试

/**
* @Description:
* @Auther: zhurongsheng
* @Date: 2020/4/25 15:05
*/

public class ListTest {
public static void main(String[] args) {
testZrsList();
System.out.println("################");
testJdkList();
}
private static void testJdkList() {
List<Integer> list = new LinkedList<>();
for (int i = 0; i < 10; i++) {
list.add(i,i);
}
list.add(5,50);
System.out.println(list.toString());
list.remove(5);
System.out.println(list.toString());
list.remove(0);
System.out.println(list.toString());
list.remove(list.size()-1);
System.out.println(list.toString());
}
private static void testZrsList(){
ZrsLinkedList<Integer> zrsList = new ZrsLinkedList<>();
for (int i = 0; i < 10; i++) {
zrsList.add(i,i);
}
zrsList.add(5,50);
System.out.println(zrsList.toString());
zrsList.remove(5);
System.out.println(zrsList.toString());
zrsList.remove(0);
System.out.println(zrsList.toString());
zrsList.remove(zrsList.size()-1);
System.out.println(zrsList.toString());
}
}

5 结果

在这里插入图片描述



推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
author-avatar
潜水的飞机537
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有