Java-链表

1、什么是链表?

2、链表的特点是什么?

3、链表的实现原理?

4、如何自己写出一个链表?


1、什么是链表?

  • 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。
  • 每一个链表都包含多个节点,节点又包含两个部分,一个是数据域(储存节点含有的信息),一个是引用域(储存下一个节点或者上一个节点的地址)。
  • 链表的理解示意图

2、链表的特点是什么?

  • 获取数据麻烦,需要遍历查找,比数组慢
  • 方便插入、删除

3、链表的实现原理

  1. 创建一个节点类,其中节点类包含两个部分,第一个是数据域(你到时候要往节点里面储存的信息),第二个是引用域(相当于指针,单向链表有一个指针,指向下一个节点;双向链表有两个指针,分别指向下一个和上一个节点)
  2. 创建一个链表类,其中链表类包含三个属性:头结点、尾节点和大小,方法包含添加、删除、插入等等方法。

单向链表的节点类:

 public class Node {
public Object data;
public Node next; public Node(Object e){
this.data = e;
}
}

双向链表的节点类:

 public class Node {
public Object e;
public Node next;
public Node pre;
public Node(){ }
public Node(Object e){
this.e = e;
next = null;
pre = null;
}
}

4、如何自己写出一个链表?

代码如下(以双向链表为例,有详细的注释,单向链表同理):

首先创建了一个节点类

 package MutuLink;

 public class Node {
public Object e;
public Node next;
public Node pre;
public Node(){ }
public Node(Object e){
this.e = e;
next = null;
pre = null;
}
}

然后创建了一个链表类

 package MutuLink;

 public class MyList {
private Node head;
private Node tail;
private int size = 0; public MyList() {
head = new Node();
tail = new Node();
head.next =null;
tail.pre = null;
} public boolean empty() {
if (head.next == null)
return true;
return false;
}
//找到所找下标节点的前一个节点
public Node findpre(int index){
Node rnode = head;
int dex = -1;
while(rnode.next != null){
//找到了插入节点的上一个节点
if( dex== index - 1){
return rnode;
}
rnode = rnode.next;
dex++;
}
return null;
}
public Node findthis(int index){
Node rnode = head;
//把rnode想象为指针,dex为指向的下标,这个地方很容易错,因为当指向最后一个节点时没有判断IF就跳出循环了
int dex = -1;
while(rnode.next != null){
if(dex == index)
return rnode;
rnode = rnode.next;
dex++;
}
if(dex == size - 1){
return rnode;
}
// Node test = new Node(new Students("haha",1,2));
return null;
} // 往链表末尾加入节点
public void add(Object e) {
Node node = new Node(e);
Node rnode = head;
//如果是空链表的话插入一个节点,这个节点的pre不能指向上一个节点,必须指空
if (this.empty()) {
rnode.next = node;
rnode.next.pre = null;
tail.pre = node;
size++;
} else {
while (rnode.next != null)
rnode = rnode.next;
rnode.next = node;
node.pre = rnode;
tail.pre = node;
size++;
}
}
//往链表的某一个标插入一个节点
public boolean add(int index,Object e){
if(index <0||index>=size)
return false;
Node node = new Node(e);
Node prenode = this.findpre(index);
node.next = prenode.next;
prenode.next.pre = node;
prenode.next = node;
node.pre = prenode;
size++;
return true;
}
public boolean add(int index,MyList myl){
if(index <0 || index >= size)
return false;
Node prenode = this.findpre(index);
// myl.tail.pre.next = prenode.next;
// prenode.pre = myl.tail.pre;
// tail.pre = null;
// prenode.next = myl.head.next;
// myl.head.next.pre = prenode;
// head.next = null;
myl.tail.pre.next = prenode.next;
prenode.next.pre = myl.tail.pre.pre;
myl.head.next.pre = prenode.pre;
prenode.next = myl.head.next;
myl.head = null;
myl.tail = null;
size+=myl.size;
return true;
} public Object remove(int index){
Object ob= this.get(index);
if(index <0 || index >= size)
return null;
//特殊情况,当移除节点是最后一个节点的时候
//较为复杂通过画图来写代码
if(index == size - 1){
Node prenode = this.findpre(index);
this.tail.pre = this.tail.pre.pre;
this.tail.pre.next.pre = null;
this.tail.pre.next =null;
size--;
return ob;
}
//比较复杂,通过画图解决
else{
Node prenode = this.findpre(index);
prenode.next = prenode.next.next;
prenode.next.pre.next = null;
prenode.next.pre = prenode.next.pre.pre;
size--;
return ob;
}
} public Object get(int index){
Node thisnode = this.findthis(index);
return thisnode.e;
}
public int size(){
return size;
}
}

最后测试

 package MutuLink;

 import java.util.Random;

 public class manage {
public static void main(String[] args) {
String name = "";
int credit;
int age;
int size;
MyList myl = new MyList();
Random random = new Random();
size = random.nextInt(5) + 1;
for (int i = 0; i < size; i++) {
credit = random.nextInt(5);
age = random.nextInt(5) + 18;
for (int j = 0; j < 4; j++) {
name += (char) (random.nextInt(26) + 97);
}
Students stu = new Students(name, credit, age);
myl.add(stu);
name = "";
} System.out.println("Size of myl1 is "+ myl.size());
for(int i = 0; i < myl.size() ;i++){
Students stu2 = (Students) myl.get(i);
stu2.show();
}
// //测试能否在链表末尾加入节点(成功)
// for(int i = 0; i < myl.size() ;i++){
// Students stu2 = (Students) myl.get(i);
// stu2.show();
// }
// //测试能否通过下标加入一个节点(成功)
// Students stu3 = new Students("cyt",5,18);
// myl.add(1, stu3);
// System.out.println("Size is "+ myl.size());
// for(int i = 0; i < myl.size() ;i++){
// Students stu2 = (Students) myl.get(i);
// stu2.show();
// } MyList myl2 = new MyList();
size = random.nextInt(5) + 1;
for (int i = 0; i < size; i++) {
credit = random.nextInt(5);
age = random.nextInt(5) + 18;
for (int j = 0; j < 4; j++) {
name += (char) (random.nextInt(26) + 97);
}
Students stu2 = new Students(name, credit, age);
myl2.add(stu2);
name = "";
}
System.out.println("Size is of myl2 "+ myl2.size());
for(int i = 0; i < myl2.size() ;i++){
Students stu2 = (Students) myl2.get(i);
stu2.show();
} myl.add(1, myl2);
System.out.println("Size is of myl1 "+ myl.size());
for(int i = 0; i < myl.size() ;i++){
Students stu2 = (Students) myl.get(i);
stu2.show();
} } }

结果输出:

这样,一个简单的双向链表就编写完成了,希望这篇博客对您有所帮助哦!

Java-链表(单向链表、双向链表)的更多相关文章

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

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

  2. 数据结构——Java实现单向链表

    结点类: /** * @author zhengbinMac * 一个OnelinkNode类的对象只表示链表中的一个结点,通过成员变量next的自引用方式实现线性表中各数据元素的逻辑关系. */ p ...

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

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

  4. Java实现单向链表

    /* 先定义一个Node类用来存储节点的值域和指针域 * 即当前节点中的值和后面节点的方法 * 在C中就是相当与定义一个结构体类型一个数据域和指针域的方法 */class LNode{//这个写法已经 ...

  5. java 实现单向链表

    package cn.com.factroy2; /** * 可以看做是操作链表的工具类,链表的核心结构就是节点的数据结构 * @author wanjn * */ public class Sing ...

  6. Java实现单向链表的增删改查

    class List<T> { private class Node { private T data; private Node next; private Node(T data) { ...

  7. Java实现单向链表反转

    public class LinkedListTest { public static void main(String[] args) { Node A = new Node("A&quo ...

  8. 数组、单链表和双链表介绍 以及 双向链表的C/C++/Java实现

    概要 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列.本章先介绍线性表的几个基本组成部分:数组.单向链表.双向链表:随后给出双向链表的C.C++和Java三种语言的实现. ...

  9. Python 单向链表、双向链表

    用面向对象实现Linkedlist链表 单向链表实现append.iternodes 双向链表实现append.pop.insert.remove.iternodes 单向链表与双向链表 单向链表: ...

  10. 用python实现单向链表

    单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 表元素域ele ...

随机推荐

  1. Python库安装注意事项

    由于一些python库依赖其它库或者其它组件,因此,在使用pip3命令安装python库的时候,经常会报错,告知缺失哪些组件. 但是, 开启VPN后,就没有再碰到类似错误,相关组件都是自动被安装. 因 ...

  2. mac ASP.NET5

    不写1行代码,在Mac上体验ASP.NET 5的最简单方法   昨天微软发布了ASP.NET 5 beta2(详见ASP.NET 5 Beta2 发布),对ASP.NET 5的好奇心又被激发了. 今天 ...

  3. 计算fibonacci数(多种方法)

    #include <iostream> using namespace std; //计算fibonacci数 //方法一:二分递归法,时间复杂度为O(2^n),额外空间复杂度为常数 in ...

  4. ls 操作命令 -l/-R和rm -r dir 功能实现

    ls -R #include <sys/stat.h> #include <dirent.h> #include <fcntl.h> #include <st ...

  5. 三、WPF 全选,反选,以及获取选中行

    页面代码 <TextBlock> <CheckBox Name="cbAllCreate" Click="CbAllCreate_Click" ...

  6. Windows Server 2008 R2 /2012 修改密码策略(摘抄 原文地址 https://www.cnblogs.com/mili3/p/7799347.html)

    今天建了域环境,在添加新用户的时候,发现用简单的密码时域安全策略提示密码复杂度不够,于是我就想在域安全策略里面把密码复杂度降低一点. 问题:    在“管理工具 >> 本地安全策略 > ...

  7. cocos ide使用binding-generator导出来的c++类

    time:2015/03/19 cocos版本:3.2 描述:用了ide运行一个实例[1]的时候需要增加c++类,正确导出来之后,直接使用vs2012启动是没有问题的,但是使用ide启动却提示找不到模 ...

  8. Python学习---网络编程 1217【all】

    OSI七层模型: 物理层, 数据链路层, 网络层,传输层,会话层,表达层,应用层 应用层:TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等 传输层:TCP,UDP 网络层:I ...

  9. Linux下的Mysql的双向同步

    在主从复制的基础上实现双向同步 [更多参考] https://www.cnblogs.com/shuidao/p/3551238.html http://blog.csdn.net/i_bruce/a ...

  10. EXP-00032: Non-DBAs may not export other users

    Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit ProductionWith the P ...