转载请注明本文出处:http://www.cnblogs.com/Starshot/p/6918569.html

链表的结构是由一个一个节点组成的,所谓链,就是每个节点的头尾连在一起。而单向链表就是:每个节点包含了当前节点的值和下一个节点引用。双向链表就是每个节点包含了当前节点的值和上下两个节点的引用。相对于数组结构,链表的增删效率会更加高。

这边文章主要讲怎么用Java实现一个简单的链表结构:单向无环链表。以及实现一些数据处理的方法。

首先,新建一个节点类(本次例子中的节点值都是字符串类型):

1 public classNode {2

3 privateString value;4 privateNode next;5

6 publicNode(String value){7 this.value=value;8 }9 publicNode(){10

11 }12

13 publicString getValue(){14 returnvalue;15 }16

17 publicNode getnext(){18 returnnext;19 }20

21 public voidsetValue(String value){22 this.value=value;23 }24

25 public voidsetNext(Node next){26 this.next=next;27 }28 }

然后再建一个链表类:

public classMyLinkedTable {

Node head=newNode();//向链表中增加值

public booleanadd(String str){

Node node=newNode(str);if(head.getnext()==null){

head.setNext(node);;return true;

}

Node tmp=head;while(tmp.getnext()!=null){

tmp=tmp.getnext();

}

tmp.setNext(node);return true;

}//已知某个节点,然后删除该节点

public booleandelete(Node node){

Node next=node.getnext();

Node nextAddress=next.getnext();

String nextValue=next.getValue();

node.setNext(nextAddress);

node.setValue(nextValue);return true;

}//删除第index个节点,index从1开始

public boolean delete(intindex){if(index>length()||index<1){return false;

}int i=1;

Node temp=head.getnext();while(i

temp=temp.getnext();

i++;

}

Node next=temp.getnext();

Node nextAddress=next.getnext();

String nextValue=next.getValue();

temp.setNext(nextAddress);

temp.setValue(nextValue);return true;

}//获得第index个节点的值

public String get(intindex){if(index>length()||index<1){return null;

}int i=1;

Node temp=head.getnext();while(i

temp=temp.getnext();

i++;

}returntemp.getValue();

}//获取链表里面数据的长度,也就是插入了多少个值。

public intlength(){if(head.getnext()==null){return 0;

}int i=1;

Node temp=head.getnext();while((temp=temp.getnext())!=null){

i++;

}returni;

}//反转链表

public voidreverseTable(){

Node node1=head.getnext();if(node1==null){return;

}

Node preNode=null;

Node curNode=node1;while(true){

Node origNextNode=curNode.getnext();

curNode.setNext(preNode);if(origNextNode==null){

head.setNext(curNode);break;

}

preNode=curNode;

curNode=origNextNode;

}

}//获取中间链表

publicString getMid(){

Node slowPointer=this.head.getnext(),fastPointer=this.head.getnext();while(fastPointer!=null&&fastPointer.getnext()!=null&&fastPointer.getnext().getnext()!=null){

slowPointer=slowPointer.getnext();

fastPointer=fastPointer.getnext().getnext();

}returnslowPointer.getValue();

}//删除重复链表

public voiddeleteDuplicateNode(){

Node nodeCur=head.getnext();if(nodeCur==null) return;while(nodeCur.getnext()!=null){

Node lastNode=nodeCur;

Node compareNode=lastNode.getnext();while(compareNode!=null){if(nodeCur.getValue().equals(compareNode.getValue())){

lastNode.setNext(compareNode.getnext());

compareNode=compareNode.getnext();

}else{

lastNode=compareNode;

compareNode=compareNode.getnext();

}

}

nodeCur=nodeCur.getnext();

}

}

}

需要说明一下,这个链表结构是以head为起始节点,head指向插入的第一个节点(反转后就是最后一个),head本身的value一直都是空的,它只作为起始节点入口存在,不参与节点的计数,所以链表的节点总数(插入数据总数)是不包括head在内的。

接下来对某些方法进行说明:

1.链表反转

//链表翻转就是把原来的1>2>3>4变成4>3>2>1,所以原来在最前面的节点要变成在最后面,最后面的要变成最前面//就是head的地址引用要变成最后一个节点的,原来head后的第一个节点的地址引用要由第二的节点变为NULL,原来第二个节点的地址引用要由第三个节点变成第一个节点//以此类推,一直翻转到最后一个。然后把head的地址引用变成最后一个。//在这个链表里面,head的位置是一直不变的,它永远是最前面,在head之后的节点才开始翻转。

public voidreverseTable(){

Node node1=head.getnext();if(node1==null){return;

}

Node preNode=null;

Node curNode=node1;while(true){

Node origNextNode=curNode.getnext();

curNode.setNext(preNode);if(origNextNode==null){

head.setNext(curNode);break;

}

preNode=curNode;

curNode=origNextNode;

}

}

2.获得中间节点:

//通过用快慢指针来找到中间节点,快指针的速度为慢指针的两倍,慢指针一次走一个节点,快指针一次走两个节点,//当快指针走到尽头时,慢指针刚好为中间值,当快指针走到倒数第二个节点时,慢指针为上中位数。//fastPointer!=null用来判断链表表内除head外有没有其它节点,fastPointer.getnext()!=null判断是否为最后一个节点,//fastPointer.getnext().getnext()!=null判断是否为倒数第二个节点。

publicString getMid(){

Node slowPointer=this.head.getnext(),fastPointer=this.head.getnext();while(fastPointer!=null&&fastPointer.getnext()!=null&&fastPointer.getnext().getnext()!=null){

slowPointer=slowPointer.getnext();

fastPointer=fastPointer.getnext().getnext();

}returnslowPointer.getValue();

}

3.删除具有相同值的节点(重复节点):

//删除具有相同值的节点//基本原理是用第一个节点的值和第二个节点值比较,然后和第三个节点比较,以此类推。此时第一个节点为当前节点nodeCur,第二第三以及之后的节点为比较节点compareNode//一轮比较完毕后,第二个节点就变成nodeCur,之后那些节点就是compareNode//如果遇到有相同的值的节点,就将该节点的上个节点的next值为该节点的下个节点:lastNode.setNext(compareNode.getnext()),此时该节点就在链表里失去引用了,就相当于删除了。//所以需要lastNode引用来保存当前比较节点的上一个节点

public voiddeleteDuplicateNode(){

Node nodeCur=head.getnext();if(nodeCur==null) return;while(nodeCur.getnext()!=null){

Node lastNode=nodeCur;

Node compareNode=lastNode.getnext();while(compareNode!=null){if(nodeCur.getValue().equals(compareNode.getValue())){

lastNode.setNext(compareNode.getnext());

compareNode=compareNode.getnext();

}else{

lastNode=compareNode;

compareNode=compareNode.getnext();

}

}

nodeCur=nodeCur.getnext();

}

}

写好之后可以测试一下:

public classTest {public static voidmain(String[] args) {

MyLinkedTable m=newMyLinkedTable();

m.add("1");

m.add("2");

m.add("3");

m.add("4");

m.add("5");

m.add("6");for(int i=1;i<=m.length();i++){

System.out.println(i+":"+m.get(i));

}

System.out.println("length:"+m.length());

m.reverseTable();for(int i=1;i<=m.length();i++){

System.out.println(i+":"+m.get(i));

}

System.out.println("length:"+m.length());

m.delete(2);for(int i=1;i<=m.length();i++){

System.out.println(i+":"+m.get(i));

}

System.out.println("length:"+m.length());

System.out.println(m.getMid());

}

}

运行输出如下:

1:1

2:2

3:3

4:4

5:5

6:6

length:6

1:6

2:5

3:4

4:3

5:2

6:1

length:6

1:6

2:4

3:3

4:2

5:1

length:5

3

还有测试删除重复节点的:

public classTest2 {public static voidmain(String[] args) {

MyLinkedTable m=newMyLinkedTable();

m.add("1");

m.add("2");

m.add("3");

m.add("2");

m.add("2");

m.add("6");for(int i=1;i<=m.length();i++){

System.out.println(i+":"+m.get(i));

}

System.out.println("length:"+m.length());

m.deleteDuplicateNode();for(int i=1;i<=m.length();i++){

System.out.println(i+":"+m.get(i));

}

System.out.println("length:"+m.length());

}

}

运行输出:

1:1

2:2

3:3

4:2

5:2

6:6

length:6

1:1

2:2

3:3

4:6

length:4

以上就是用java实现单向无环链表的详细过程和解释,如果不妥之处,欢迎指出。

java链表对象_用Java实现链表结构对象:单向无环链表相关推荐

  1. 链表问题11——两个单链表相交的系列问题(二):找到两个无环链表的交点

    题目 判断两个无环链表是否相交,相交则返回第一个相交节点,否则返回null 思路 分别遍历链表1和链表2,最后一个节点分别即为end1和end2,长度分别记为len1和len2 如果end1不等于en ...

  2. 左神算法:两个单链表相交的一系列问题(链表是否有环 / 两无环链表是否相交 / 两有环链表是否相交)

    本题来自左神<程序员代码面试指南>"两个单链表相交的一系列问题"题目. 题目 在本题中,单链表可能有环,也可能无环.给定两个单链表的头节点 head1 和 head2, ...

  3. java robot 对象_用Java Robot对象实现服务器屏幕远程监视

    用Java Robot对象实现服务器屏幕远程监视 作者:李鲁群 摘要: 有时候,在Java应用程序开发中,如:远程监控或远程教学,常常需要对计算机的屏幕进行截取,由于屏幕截取是比较接近操作系统的操作, ...

  4. java 字节码对象_获得类的字节码对象的三种方式

    java源码(xxx.java)通过编译后形成字节码文件,字节码文件通过类加载器获得字节码对象, 通过字节码对象可以操作源码中的属性和方法. 方式一,使用类的class属性: Class clazz1 ...

  5. java clone 序列化_关于Java对象深度Clone以及序列化与反序列化的使用

    ‍        我们可以利用clone方法来实现对象只见的复制,但对于比较复杂的对象(比如对象中包含其他对象,其他对象又包含别的对象.....)这样我们必须进行层层深度clone,每个对象需要实现 ...

  6. java 共享软件 保护_【Java并发.3】对象的共享

    本章将介绍如何共享和发布对象,从而使他们能够安全地由多个线程同时访问.这两章合在一起就形成了构建线程安全类以及通过java.util.concurrent 类库来构建开发并发应用程序的重要基础. 3. ...

  7. java反射创建带参数对象_反射 Java反射对象创建 - 闪电教程JSRUN

    Java反射 -Java反射对象创建 我们可以使用反射动态创建类的对象.通过调用其中一个构造函数. 然后我们可以访问对象的细分的值,设置它们的值,并调用它们的方法. 有两种方法来创建对象: 使用no- ...

  8. java如果把字符串转成对象_为什么Java中的字符串对象是不可变的,有什么好处?...

    专注于Java领域优质技术号,欢迎关注 原创: 阿杜的世界 阅读本文大概需要 4分钟. 所谓不可变对象,是指一个对象在创建后,它的内部状态不会被改变的对象.这意味着当我们将一个不可变对象的引用赋值给某 ...

  9. java有几大对象_一个 Java 对象到底有多大?

    阅读本文大概需要 2.8 分钟. 出处:http://u6.gg/swLPg 编写 Java 代码的时候,大多数情况下,我们很少关注一个 Java 对象究竟有多大(占据多少内存),更多的是关注业务与逻 ...

最新文章

  1. 服务器虚拟交换机到网卡不通,浅析虚拟化环境网卡绑定模式
  2. 从零开始学电脑办公_电脑办公从零开始
  3. c++中默认32位int类型转换截取高位部分
  4. SpringBoot(笔记)
  5. 日语输入法电脑版_日语轻松入门小百科
  6. npm install Saving to file: /root/.jenkins/workspace/ems-web/node_modules/chromedriver/2
  7. MySQL基础操作命令
  8. bscroll.js
  9. 基于大数据平台的数据仓库
  10. 小白怎么入门网络安全?看这篇就够啦!
  11. Python实现“求职APP网络爬虫”
  12. excle统计不同的内容的单元格个数
  13. java写接口给前端_看看人家那后端API接口写得,那叫一个优雅!
  14. java获取经纬度和地址等工具类
  15. kindle的xray怎么用_Kindle 使用小技巧之 X-Ray 功能
  16. 让人傻傻分不清的TDD、ATDD、BDD
  17. HTML5与视频传输_拔剑-浆糊的传说_新浪博客
  18. nginx.conf文件(原始无修改)
  19. DPCM编码解码的原理
  20. noip考前复习计划提醒(显然不全)

热门文章

  1. mac ---- 安装nginx
  2. java ios rsa解密乱码_java与IOS之间的RSA加解密
  3. mysql-5.7.24-linux_Linux下安装mysql-5.7.24
  4. sap后台配置原因代码_【MM配置】Inventory Management 库存管理
  5. 方形物体绕中心旋转的扭力_转轴扭力测试方案
  6. 这是一个无效的源路径/url
  7. 由方位角和长度如何确定坐标 已知第一个点的坐标
  8. java去掉的行_Java实现去掉每行的行号
  9. python 描述符的应用
  10. MySQL/InnoDB中,乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念的理解...