一、单向链表的结构。
(1)、首先节点的结构,其中包含本节点内容,以及需要指向下一个节点。
Java代码
private static class Entry<E>{
E e;
Entry<E> nextEntry;
public Entry(E e,Entry<E> nextEntry){
this.e=e;
this.nextEntry=nextEntry;
}
}
private static class Entry<E>{
E e;
Entry<E> nextEntry;
public Entry(E e,Entry<E> nextEntry){
this.e=e;
this.nextEntry=nextEntry;
}
}Java代码
Java代码
其中e则指向本节点的对象,而nextEntry则指向下一个节点。
(2)、任何时候都需要知道表头在哪里。毕竟是单向链表嘛,因为只有一个方向,找到了表头就能找到全部。
Java代码
private  Entry<E> head;
private  Entry<E> head;
(3)、还可以记录链表中总共有多少个节点。它是在某些判断时为了提高效率而存在的。不是绝对需要的。毕竟知道表头后,一个一个按顺序去寻找就好了。
Java代码
private  int size;
public int size(){
return this.size;
}
private  int size;
public int size(){
return this.size;
}
Java代码
好了有这三样,就足够了。就看我们如何用他们了。
二、内部实现。
(1)、第一次向链表中插入。此时链表中节点为null,第一次插入,无非就是把节点头插入而已。
可以看出就是把链表头初始化了,并且链表大小涨1。其中modCount记录整个链表修改的次数,链表的增加和删除它都会增加。毕竟第一次插入相对外调用是透明的,所以应该是私有的咯。(透明就是不可见,这里只得是外部没必要知道它的存在)
Java代码
private void addFirst(E e){
head=new Entry<E>(e,null);
size++;
modCount++;
}
private void addFirst(E e){
head=new Entry<E>(e,null);
size++;
modCount++;
}
(2)、表头插入。在链表的头前插入一个元素,新增的元素变成新的表头。这个插入是效率最高的,毕竟你时刻知道链表的头在哪里。
Java代码
public void addHead(E e){
if(head==null){
this.addFirst(e);
}else{
Entry<E> newEntry=new Entry<E>(e,head);
head=newEntry;
size++;
modCount++;
}
}
public void addHead(E e){
if(head==null){
this.addFirst(e);
}else{
Entry<E> newEntry=new Entry<E>(e,head);
head=newEntry;
size++;
modCount++;
}
}可以看出头为null的时候,则表明链表中没值,只需调用第一次插入。否则对给定的元素创新增一个节点,新增节点的下一个指向头节点,当然此时自己已经变成头结点了,索引要更新头节点的引用。(可以看出想要清空链表,只需要将头置为null就好了)
(3)、指定节点插入(插队)。在链表的指定节点插入一个元素,效率非常低。由于规则上你只能从队伍第一个开始往后找,找到你要插队位置的前一个,并将你插入其中,你先要告诉你身前人你在他身后,并且你自己要清楚你身后是谁。反正够麻烦的。
Java代码
public void addSpecifyIndex(E e,int index){
if(index<0||index>size||size==0){
throw new NoSuchElementException();
}
if(index==0){
this.addHead(e);
return;
}
int count=0;
for (Entry<E> p=head; p!=null;p=p.nextEntry) {
if(count+1==index){
Entry<E> newEntry=new Entry<E>(e,p.nextEntry);
p.nextEntry=newEntry;
size++;
modCount++;
return;
}
count++;
}
}
public void addSpecifyIndex(E e,int index){
if(index<0||index>size||size==0){
throw new NoSuchElementException();
}
if(index==0){
this.addHead(e);
return;
}
int count=0;
for (Entry<E> p=head; p!=null;p=p.nextEntry) {
if(count+1==index){
Entry<E> newEntry=new Entry<E>(e,p.nextEntry);
p.nextEntry=newEntry;
size++;
modCount++;
return;
}
count++;
}
}
Java代码
先进行判断index是否正确,规定不能插入null链表。而且不能跳着走,毕竟链表要连起来。由于要找到前一个,但是表头的前一个是没有的,所以index==0时要单独判断。后面则用count进行计数,找到其index-1节点,然后进行插队处理。
(4)、尾插入。其实也是插队了,只是总是需要插到最后一个之后。
Java代码
public void add(E e){
if(head==null){
this.addFirst(e);
}else{
this.addSpecifyIndex(e, size);
}
}
public void add(E e){
if(head==null){
this.addFirst(e);
}else{
this.addSpecifyIndex(e, size);
}
}
(5)、指定节点获取元素。效率低,同样从头开始找到指定的节点把其中元素取出
Java代码
public E get(int index){
if(index<0||index>=size){
throw new NoSuchElementException();
}
E result=null;
int count=0;
for (Entry<E> p=head;p!=null;p=p.nextEntry) {
if(count==index){
result=p.e;
}
count++;
}
return result;
}
public E get(int index){
if(index<0||index>=size){
throw new NoSuchElementException();
}
E result=null;
int count=0;
for (Entry<E> p=head;p!=null;p=p.nextEntry) {
if(count==index){
result=p.e;
}
count++;
}
return result;
}
Java代码
(6)、指定节点删除。效率低,同样需要找到指定节点前一节点,直接把指定节点跳过就好了。
Java代码
public void remove(int index){
if(index<0||index>=size){
throw new NoSuchElementException();
}
if(index==0){
head=head.nextEntry;
size--;
modCount++;
return;
}
int count=0;
for (Entry<E> p=head;p.nextEntry!=null;p=p.nextEntry) {
if(count+1==index){
p.nextEntry=p.nextEntry.nextEntry;
size--;
modCount++;
break;
}
count++;
}
}
public void remove(int index){
if(index<0||index>=size){
throw new NoSuchElementException();
}
if(index==0){
head=head.nextEntry;
size--;
modCount++;
return;
}
int count=0;
for (Entry<E> p=head;p.nextEntry!=null;p=p.nextEntry) {
if(count+1==index){
p.nextEntry=p.nextEntry.nextEntry;
size--;
modCount++;
break;
}
count++;
}
}
(7)、循环。为了好进行遍历演示,下面的就是循环遍历所用的了,大家随意看一下就好了。
Java代码
private transient Entry<E> current;
public void setCursor(int index){
if(index<0||index>=size){
throw new NoSuchElementException();
}
int count=0;
for (Entry<E> p=head;p!=null;p=p.nextEntry) {
if(count==index){
current=p;
break;
}
count++;
}
}
public boolean hasNext(){
return current!=null;
}
public E next(){
E result=current.e;
current=current.nextEntry;
return result;
}
private transient Entry<E> current;
public void setCursor(int index){
if(index<0||index>=size){
throw new NoSuchElementException();
}
int count=0;
for (Entry<E> p=head;p!=null;p=p.nextEntry) {
if(count==index){
current=p;
break;
}
count++;
}
}
public boolean hasNext(){
return current!=null;
}
public E next(){
E result=current.e;
current=current.nextEntry;
return result;
}
三、测试。。一个main方法,测试一下。
Java代码
public static void main(String[] args) {
SingleChain<String> singleChain=new SingleChain<String>();
for (int i = 0; i < 4; i++) {
singleChain.add(i+"");
}
//头插入
//      singleChain.addHead("head");
//尾插入
//      singleChain.add("tail");
//指定节点插入
//      singleChain.addSpecifyIndex("Specify", 1);
//指定节点删除
//      singleChain.remove(3);
//设置循环的初始节点
singleChain.setCursor(0);
int count=0;
System.out.println("######SIZE"+singleChain.size()+"#######");
while(singleChain.hasNext()){
System.out.println("index:"+count+",entry:"+singleChain.next());
count++;
}
System.out.println(singleChain.get(singleChain.size()-1));
}
public static void main(String[] args) {
SingleChain<String> singleChain=new SingleChain<String>();
for (int i = 0; i < 4; i++) {
singleChain.add(i+"");
}
//头插入
//      singleChain.addHead("head");
//尾插入
//      singleChain.add("tail");
//指定节点插入
//      singleChain.addSpecifyIndex("Specify", 1);
//指定节点删除
//      singleChain.remove(3);
//设置循环的初始节点
singleChain.setCursor(0);
int count=0;
System.out.println("######SIZE"+singleChain.size()+"#######");
while(singleChain.hasNext()){
System.out.println("index:"+count+",entry:"+singleChain.next());
count++;
}
System.out.println(singleChain.get(singleChain.size()-1));
}
四、全部代码
Java代码
package paladin.chain;
import java.util.NoSuchElementException;
public class SingleChain<E> implements Chain<E>{
private  Entry<E> head;
private transient Entry<E> current;
private  int size;
private  int modCount;
private void addFirst(E e){
head=new Entry<E>(e,null);
size++;
modCount++;
}
public void addHead(E e){
if(head==null){
this.addFirst(e);
}else{
Entry<E> newEntry=new Entry<E>(e,head);
head=newEntry;
size++;
modCount++;
}
}
public void addSpecifyIndex(E e,int index){
if(index<0||index>size||size==0){
throw new NoSuchElementException();
}
if(index==0){
this.addHead(e);
return;
}
int count=0;
for (Entry<E> p=head; p!=null;p=p.nextEntry) {
if(count+1==index){
Entry<E> newEntry=new Entry<E>(e,p.nextEntry);
p.nextEntry=newEntry;
size++;
modCount++;
return;
}
count++;
}
}
public void add(E e){
if(head==null){
this.addFirst(e);
}else{
this.addSpecifyIndex(e, size);
}
}
public E get(int index){
if(index<0||index>=size){
throw new NoSuchElementException();
}
E result=null;
int count=0;
for (Entry<E> p=head;p!=null;p=p.nextEntry) {
if(count==index){
result=p.e;
}
count++;
}
return result;
}
public void remove(int index){
if(index<0||index>=size){
throw new NoSuchElementException();
}
if(index==0){
head=head.nextEntry;
size--;
modCount++;
return;
}
int count=0;
for (Entry<E> p=head;p.nextEntry!=null;p=p.nextEntry) {
if(count+1==index){
p.nextEntry=p.nextEntry.nextEntry;
size--;
modCount++;
break;
}
count++;
}
}
public void setCursor(int index){
if(index<0||index>=size){
throw new NoSuchElementException();
}
int count=0;
for (Entry<E> p=head;p!=null;p=p.nextEntry) {
if(count==index){
current=p;
break;
}
count++;
}
}
public boolean hasNext(){
return current!=null;
}
public E next(){
E result=current.e;
current=current.nextEntry;
return result;
}
public int size(){
return this.size;
}
public static void main(String[] args) {
SingleChain<String> singleChain=new SingleChain<String>();
for (int i = 0; i < 4; i++) {
singleChain.add(i+"");
}
//头插入
//      singleChain.addHead("head");
//尾插入
//      singleChain.add("tail");
//指定节点插入
//      singleChain.addSpecifyIndex("Specify", 1);
//指定节点删除
//      singleChain.remove(3);
//设置循环的初始节点
singleChain.setCursor(0);
int count=0;
System.out.println("######SIZE"+singleChain.size()+"#######");
while(singleChain.hasNext()){
System.out.println("index:"+count+",entry:"+singleChain.next());
count++;
}
System.out.println(singleChain.get(singleChain.size()-1));
}
private static class Entry<E>{
E e;
Entry<E> nextEntry;
public Entry(E e,Entry<E> nextEntry){
this.e=e;
this.nextEntry=nextEntry;
}
}
}

java实现单向链表相关推荐

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

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

  2. Java实现单向链表——精简

    文章目录 引言 实现思路 添加元素 插入元素 删除元素 查找元素 更新元素 显示链表 实现代码(完整) 总结 留言 引言 链表是一种重要的数据结构.它的存储空间是不连续的,单向链表是最简单的一种链表. ...

  3. java集合单向链表_Java实现单向链表数据结构

    本文章同步到本人的博客站点 燕归来 链表是一种数据结构,和数组同级.比如,Java中我们使用的ArrayList,其实现原理是数组.而LinkedList的实现原理就是链表了.链表在进行循环遍历时效率 ...

  4. java实现单向链表的增、删、改、查

    单向链表 作者:vashon package com.ywx.link; /*** 单向链表* @author vashon**/ public class LinkTest {public stat ...

  5. java简单单向链表_用java简单的实现单链表的基本操作

    packagecom.tyxh.link;//节点类 public classNode {protected Node next; //指针域 protected int data;//数据域 pub ...

  6. java简单单向链表_【新手自白书】简单单项链表的实现(JAVA)

    复习一下简单单项链表的实现. 在动手写链表之前,需要思考链表是如何组成的,一般来说,一个简单的单项链表主要是由节点构成,由于链表的特性,头节点是一个十分重要的成员,所以,链表必须的成员是节点Node, ...

  7. 用Java实现单向链表

    [说明] 封装节点类,既用于存储数据data和下一个节点的首地址next,又封装了基本的增删改查的功能. 方便以后调用,而不用要用户手工去处理各个节点的关系. //class Link{ privat ...

  8. 【java】Java实现单向链表反转

    1.概述 转载:https://www.jb51.net/article/136185.htm 遇到了这个问题,记录一下 2.案例1 2.1 实现思路 递归:从尾部开始处理 非递归:从头部开始处理 2 ...

  9. 反转单向链表java_Java实现单向链表反转

    本文实例为大家分享了Java实现单向链表反转的具体代码,供大家参考,具体内容如下 1.实现代码 public class LinkedListTest { public static void mai ...

最新文章

  1. ansys大变形开关要不要打开_ANSYS网格质量评定指标介绍
  2. 裁员大潮来袭,程序员面试的这些技巧收藏好!
  3. 人工智能即将冲击与改变现有的医疗方式
  4. 使用VSCode调试C#控制台程序
  5. 判断数字是否在区间 python实现
  6. Vue.js 状态过渡
  7. java基础:数据类型
  8. 【图像处理】——Python鼠标框选ROI(感兴趣)区域并且保存(含鼠标事件)
  9. win10打字突然变成繁体
  10. 2729: [HNOI2012]排队
  11. jQuery hasAttr检查元素是否有属性[重复]
  12. Python批量下载中国大学MOOC课件
  13. DataInputStream和DataOutputStream
  14. Matplotlib系列(一):快速绘图入门
  15. jgit git pull_使用JGit API探索Git内部
  16. 沈阳中小学教材2022春季版
  17. python语言是一个优秀的面向对象语言_Python是纯的面向对象语言吗?
  18. with复合结构小结
  19. 前端常见的8种设计模式
  20. C语言基础之四舍五入

热门文章

  1. TSM对Oracle数据库备份脚本
  2. 移动三国己然鼎立,普​通开发者如何选择开发​平台?
  3. sdwan支持的网络设备类型
  4. 使用SD-WAN策略与传统路由器的OFFICE 365配置
  5. MPLS转发过程中涉及的相关概念—Vecloud微云
  6. centos6.5配置linux dhcp
  7. python知识思维导图
  8. mysql select 1
  9. 将decimal类型的数据转成2.12这样价钱的显示方式
  10. ConcurrentModificationException 问题