package com.session.link;

/**
* 单向链表
*/
public class LinkedList<T> {
private Node head;//指向链表头节点的引用变量
private Node tail;//指向链表尾节点的引用变量
int size;//链表中当前总节点数 private class Node {
private T data;//保存数据
private Node next;//下一个节点 public Node(T data, Node next) {
this.data = data;
this.next = next;
} }
//生成链表对象是一个空表
public LinkedList() {
head = null;
tail = null;
} //生成链表对象时有一个头节点 (有参构造器)
public LinkedList(T data) {
head = new Node(data, null);//指定一个头节点的数据域值为data,不指向其他节点
tail = head;
size++;
} //返回链表的长度
public int length() {
return size;
} //获取指定位置的元素
public T getElement(int index) {
return findNodeByIndex(index).data;
} //查找 指定索引位置的节点
public Node findNodeByIndex(int index) {
if (index < 0 || index > size - 1) {
throw new IndexOutOfBoundsException("线性表索引越界");
}
Node current = head;//从头节点开始下移遍历
for (int i = 0; i < size & current.next != null; i++, current = current.next) {
if (i == index) {
return current;
}
}
return null;
} //查找 指定元素的位置(查找数据域存放的是element的节点位置)
public int findIndexByElement(T element) {
Node current = head;//从第一个节点开始查找对比数据
for (int i = 0; i < size & current.next != null; i++, current = current.next) {
if (current.data.equals(element))
return i;
}
return -1;
} //插入 在指定位置插入一个元素
public void insert(int index, T element) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("线性表索引越界");
}
if (head == null)//如果链表为空,直接调用add方法
{
add(element);
} else //链表不为空时
{
if (index == 0)//在链表头插入
{
addAtHead(element);
} else {
Node prev = findNodeByIndex(index - 1);//找到要插入位置的前一个节点
prev.next = new Node(element, prev.next);//插入后prev的next指向新节点,新节点的next指向原来prev的下一个节点
size++;
}
} } //插入 尾插法在每次在链表尾添加新节点
public void add(T element) {
if (head == null) {
head = new Node(element, null);
tail = head;
} else {
Node newNode = new Node(element, null);
tail.next = newNode;
tail = newNode;
}
size++;
} //插入 头插法在链表头部加入新节点
public void addAtHead(T element) {
//在头部插入新节点,就是让新节点的next指向原来的head,让新节点作为链表的头节点
head = new Node(element, head);
//newNode.next = head;
//head = newNode;
//如果插入之前是空链表
if (tail == null) {
tail = head;
}
} //删除指定位置的节点 返回删除节点中的元素值
public T delete(int index) {
Node deleteNode = null;
if (index < 0 || index > size - 1) {
throw new IndexOutOfBoundsException("线性表索引越界");
}
if (index == 0)//删除头节点
{
deleteNode = head;
head = head.next;
} else { Node prev = findNodeByIndex(index - 1);//获取要删除的节点的前一个节点 deleteNode = prev.next;//要删除的节点就是prev的next指向的节点 prev.next = deleteNode.next;//删除以后prev的next指向被删除节点之前所指向的next deleteNode.next = null; } return deleteNode.data; } //删除 链表中最后一个元素 public T removeLast() { return delete(size - 1); } //清除链表中所有的元素 public void clear() { head = null; tail = null; size = 0; } //判断链表是否为空 public boolean isEmpty() { return size == 0; } public String toString()//链表的输出 重写toString方法 { if(isEmpty()) { return "[]"; } else { StringBuilder sb = new StringBuilder("[");//使用StringBuilder类 for(Node current = head;current != null ; current = current.next)//从head开始遍历 { sb.append(current.data.toString()+",");//把节点的数据拼接起来 } int len = sb.length(); return sb.delete(len-1,len).append("]").toString();//把最后一个元素的,删除然后加上] } } public static void main(String[] args) { LinkedList<String> list = new LinkedList<String>(); list.add("aa"); list.add("bb"); list.add("cc"); System.out.println(list); list.addAtHead("11"); list.insert(1,"22"); System.out.println(list); list.delete(2); System.out.println(list); list.clear(); System.out.println(list); new java.util.LinkedList<>().remove() }}

JAVA 单向链表的更多相关文章

  1. JAVA单向链表实现

    JAVA单向链表实现 单向链表 链表和数组一样是一种最常用的线性数据结构,两者各有优缺点.数组我们知道是在内存上的一块连续的空间构成,所以其元素访问可以通过下标进行,随机访问速度很快,但数组也有其缺点 ...

  2. Java 单向链表学习

    Java 单向链表学习 链表等同于动态的数组:可以不同设定固定的空间,根据需要的内容动态的改变链表的占用空间和动态的数组同一形式:链表的使用可以更加便于操作. 链表的基本结构包括:链表工具类和节点类, ...

  3. java 单向链表实现

    1 class Node{//Node类 2 private String data; 3 private Node next; 4 public Node(String data){ 5 this. ...

  4. JAVA单向/双向链表的实现

    一.JAVA单向链表的操作(增加节点.查找节点.删除节点) class Link { // 链表类 class Node { // 保存每一个节点,此处为了方便直接定义成内部类 private Str ...

  5. (原创)用Java实现链表结构对象:单向无环链表

    转载请注明本文出处:http://www.cnblogs.com/Starshot/p/6918569.html 链表的结构是由一个一个节点组成的,所谓链,就是每个节点的头尾连在一起.而单向链表就是: ...

  6. Java实现单向链表基本功能

    一.前言 最近在回顾数据结构与算法,有部分的算法题用到了栈的思想,说起栈又不得不说链表了.数组和链表都是线性存储结构的基础,栈和队列都是线性存储结构的应用- 本文主要讲解单链表的基础知识点,做一个简单 ...

  7. [Java算法分析与设计]--单向链表(List)的实现和应用

    单向链表与顺序表的区别在于单向链表的底层数据结构是节点块,而顺序表的底层数据结构是数组.节点块中除了保存该节点对应的数据之外,还保存这下一个节点的对象地址.这样整个结构就像一条链子,称之为" ...

  8. 线性表的Java实现--链式存储(单向链表)

    单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始. 链式存储结构的线性表将采用一组任意的存储单元存放线性表中的数据元素.由于不需要按顺序存储,链表在 ...

  9. java对单向单向链表的操作

    概述:众所周知,数据对于数据的存储时连续的,也就是说在计算机的内存中是一个整体的.连续的.不间断的ADT数据结构.伴随的问题也会随之出现,这样其实对于内存的动态分配是不灵活的.而链表具备这个优点.因此 ...

随机推荐

  1. Apache 配置ArcGIS server/portal 反向代理

    背景 处于安全,负载均衡,访问加速等原因会对服务器启用反向代理.arcgis for server的默认的访问地址为http://server:6080/arcgis.这个时候端口和实例名都暴露了.可 ...

  2. python学习笔记(四)— 函数

    一.函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序),在Pasc ...

  3. 【使用时发生的意外】HDFS 分布式写入问题 AlreadyBeingCreatedException

    进行追加文件时出现AlreadyBeingCreatedException错误 堆栈信息大致如下: org.apache.hadoop.ipc.RemoteException(org.apache.h ...

  4. 【我的Android进阶之旅】快速创建和根据不同的版本类型(Dev、Beta、Release)发布Android 开发库到Maven私服

    前言 由于项目越来越多,有很多公共的代码都可以抽取出一个开发库出来传到公司搭建好的Maven私服,以供大家使用. 之前搭建的Maven仓库只有Release和Snapshot两个仓库,最近由于开发库有 ...

  5. django URL的补充 默认值 传多个参数

    url 后面还可以加上默认值 默认值 url(r'^index/', views.index, {'name': 'root'}), urls.py url对应关系 from django.conf. ...

  6. 线程管理coroutine

    非常好用的协程库,也可以当作线程管理来用 #include "coroutine.h" #include <stdio.h> struct args { int n; ...

  7. PAT 1146 Topological Order[难]

    1146 Topological Order (25 分) This is a problem given in the Graduate Entrance Exam in 2018: Which o ...

  8. Mediakit报告设备商的空间不足以执行此操作的纯MAC解法

    使用Mac对磁盘进行分区,显示“Mediakit报告设备商的空间不足以执行此操作”,该怎么办? What 买了一个4TB的移动硬盘,准备进行分区给Time Machine用. 硬盘自带是HDFS的,所 ...

  9. 工作笔记——js与文件上传下载

    1 js判断上传文件的后缀名,文件大小 //判断照片大小 function getPhotoSize(obj){ photoExt=obj.value.substr(obj.value.lastInd ...

  10. 三张图看遍Linux性能监控、测试、优化工具

    Linux 平台上的性能工具有很多,眼花缭乱,长期的摸索和经验发现最好用的还是那些久经考验的.简单的小工具.系统性能专家 Brendan D. Gregg在最近的 LinuxCon NA 2014 大 ...