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. angular(一)

    angularjs第一章•angluarjs介绍·什么是angularjs•AngularJS 是一个为动态WEB应用设计的结构框架,提供给大家一种新的开发应用方式,这种方式可以让你扩展HTML的语法 ...

  2. 在HTML里面HEAD部分的META元素要表达的内容是什么

    1.name属性主要有以下几种参数: A.Keywords(关键字) 说明:keywords用来告诉搜索引擎你网页的关键字是什么. 举例:<meta name ="keywords&q ...

  3. Flask-Session SQLAlchemy Script Migrate wtforms

    Flask-session Flask-session跟框架自带的session有什么区别呢~ 框架自带的session是通过请求上下文~放入到Local中的~那如果我们想把session放入别的地方 ...

  4. 图文讲解zabbix安装全过程(5)

    在了解<zabbix硬件.软件需求>之后,在你心里应该有备选的机器.今天开始安装zabbix.zabbix需要LNMP或者LAMP环境.环境的搭建不在本章范围内. LNMP环境配置Linu ...

  5. django+celery 实现定时任务

    利用 celery 实现定时任务 celery支持定时任务,设定好任务的执行时间,celery就会定时自动帮你执行, 这个定时任务模块叫celery beat Celery安装 由于celery 4. ...

  6. POJ2480:Longge's problem(欧拉函数的应用)

    题目链接:传送门 题目需求: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N ...

  7. FTP服务器文件上传的代码实现

    方式一: @Test public void testFtpClient() throws Exception { // 1.创建一个FtpClient对象 FTPClient ftpClient = ...

  8. Code signing is required for product type 'Application' in SDK 'iOS 11.2'

    在打包的时候出现这样一个错误,Code signing is required for product type 'Application' in SDK 'iOS 11.2'  ,就是说代码签名证书 ...

  9. What does Quick Sort look like in Python?

    Let's talk about something funny at first. Have you ever implemented the Quick Sort algorithm all by ...

  10. .net:Code First 创建或更新数据库

    控制台输入命令: 切换到项目的project.json 文件所在文件 dotnet ef migrations add XXX dotnet ef database update Visual Stu ...