java链表对象_用Java实现链表结构对象:单向无环链表
转载请注明本文出处: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实现链表结构对象:单向无环链表相关推荐
- 链表问题11——两个单链表相交的系列问题(二):找到两个无环链表的交点
题目 判断两个无环链表是否相交,相交则返回第一个相交节点,否则返回null 思路 分别遍历链表1和链表2,最后一个节点分别即为end1和end2,长度分别记为len1和len2 如果end1不等于en ...
- 左神算法:两个单链表相交的一系列问题(链表是否有环 / 两无环链表是否相交 / 两有环链表是否相交)
本题来自左神<程序员代码面试指南>"两个单链表相交的一系列问题"题目. 题目 在本题中,单链表可能有环,也可能无环.给定两个单链表的头节点 head1 和 head2, ...
- java robot 对象_用Java Robot对象实现服务器屏幕远程监视
用Java Robot对象实现服务器屏幕远程监视 作者:李鲁群 摘要: 有时候,在Java应用程序开发中,如:远程监控或远程教学,常常需要对计算机的屏幕进行截取,由于屏幕截取是比较接近操作系统的操作, ...
- java 字节码对象_获得类的字节码对象的三种方式
java源码(xxx.java)通过编译后形成字节码文件,字节码文件通过类加载器获得字节码对象, 通过字节码对象可以操作源码中的属性和方法. 方式一,使用类的class属性: Class clazz1 ...
- java clone 序列化_关于Java对象深度Clone以及序列化与反序列化的使用
我们可以利用clone方法来实现对象只见的复制,但对于比较复杂的对象(比如对象中包含其他对象,其他对象又包含别的对象.....)这样我们必须进行层层深度clone,每个对象需要实现 ...
- java 共享软件 保护_【Java并发.3】对象的共享
本章将介绍如何共享和发布对象,从而使他们能够安全地由多个线程同时访问.这两章合在一起就形成了构建线程安全类以及通过java.util.concurrent 类库来构建开发并发应用程序的重要基础. 3. ...
- java反射创建带参数对象_反射 Java反射对象创建 - 闪电教程JSRUN
Java反射 -Java反射对象创建 我们可以使用反射动态创建类的对象.通过调用其中一个构造函数. 然后我们可以访问对象的细分的值,设置它们的值,并调用它们的方法. 有两种方法来创建对象: 使用no- ...
- java如果把字符串转成对象_为什么Java中的字符串对象是不可变的,有什么好处?...
专注于Java领域优质技术号,欢迎关注 原创: 阿杜的世界 阅读本文大概需要 4分钟. 所谓不可变对象,是指一个对象在创建后,它的内部状态不会被改变的对象.这意味着当我们将一个不可变对象的引用赋值给某 ...
- java有几大对象_一个 Java 对象到底有多大?
阅读本文大概需要 2.8 分钟. 出处:http://u6.gg/swLPg 编写 Java 代码的时候,大多数情况下,我们很少关注一个 Java 对象究竟有多大(占据多少内存),更多的是关注业务与逻 ...
最新文章
- 服务器虚拟交换机到网卡不通,浅析虚拟化环境网卡绑定模式
- 从零开始学电脑办公_电脑办公从零开始
- c++中默认32位int类型转换截取高位部分
- SpringBoot(笔记)
- 日语输入法电脑版_日语轻松入门小百科
- npm install Saving to file: /root/.jenkins/workspace/ems-web/node_modules/chromedriver/2
- MySQL基础操作命令
- bscroll.js
- 基于大数据平台的数据仓库
- 小白怎么入门网络安全?看这篇就够啦!
- Python实现“求职APP网络爬虫”
- excle统计不同的内容的单元格个数
- java写接口给前端_看看人家那后端API接口写得,那叫一个优雅!
- java获取经纬度和地址等工具类
- kindle的xray怎么用_Kindle 使用小技巧之 X-Ray 功能
- 让人傻傻分不清的TDD、ATDD、BDD
- HTML5与视频传输_拔剑-浆糊的传说_新浪博客
- nginx.conf文件(原始无修改)
- DPCM编码解码的原理
- noip考前复习计划提醒(显然不全)
热门文章
- mac ---- 安装nginx
- java ios rsa解密乱码_java与IOS之间的RSA加解密
- mysql-5.7.24-linux_Linux下安装mysql-5.7.24
- sap后台配置原因代码_【MM配置】Inventory Management 库存管理
- 方形物体绕中心旋转的扭力_转轴扭力测试方案
- 这是一个无效的源路径/url
- 由方位角和长度如何确定坐标 已知第一个点的坐标
- java去掉的行_Java实现去掉每行的行号
- python 描述符的应用
- MySQL/InnoDB中,乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念的理解...