1,本程序实现了线性表的链式存储结构。实现的链表带有两个指针,一个始终指向链表中的第一个结点,另一个指针始终指向链表中的最后一个结点。

之所以设置尾指针,是因为,在插入元素到链表中的末尾时,可以通过尾指针直接找到链表的最后一个元素,从而不需要遍历链表就可以完成插入操作。

2,具体实现链表的类名为LList2.java,它首先实现了线性表的接口ListInterface,该接口的定义见:http://www.cnblogs.com/hapjin/p/4549492.html

LList2.java的代码 如下:

  1. public class LList2<T> implements ListInterface<T>{
  2.  
  3. private Node firstNode;//指向第一个结点的指针,该链表是不带头结点的单链表
  4. private Node lastNode;//尾指针,指向链表中的最后一个结点
  5. private int length;//表示单链表的长度
  6.  
  7. //Node类中不需要定义访问属性的get方法以及set方法,因为Node是内部类,内部类的属性可以直接在外部类中被访问
  8. class Node{
  9. //Node是内部类,其外部类中已经定义了T,故可以在这里使用通配符T
  10. private T data;//结点的数据部分
  11. private Node next;//结点的指针部分,指向下一个结点
  12. //Node类中不需要默认构造器
  13. public Node(T dataPortion){
  14. data = dataPortion;
  15. }
  16. public Node(T dataPortion, Node nextNode){
  17. data = dataPortion;
  18. next = nextNode;
  19. }
  20. }
  21.  
  22. public LList2(){
  23. clear();
  24. }
  25. //获取链表中指定位置处的结点
  26. private Node getNodeAt(int givenPosition){
  27. assert (!isEmpty() && ((1 <= givenPosition) && (givenPosition <= length)));
  28. Node currentNode = firstNode;
  29. for(int counter = 1; counter < givenPosition; counter++){
  30. currentNode = currentNode.next;
  31. }
  32. assert currentNode != null;
  33. return currentNode;
  34. }
  35.  
  36. @Override
  37. public boolean add(T newEntry) {
  38. Node newNode = new Node(newEntry);
  39. if(isEmpty()){//插入第一个结点
  40. firstNode = newNode;
  41. }
  42. else{//在其它位置插入结点
  43. lastNode.next = newNode;
  44. }
  45. lastNode = newNode;
  46. length++;
  47. return true;
  48. }
  49.  
  50. @Override
  51. public boolean add(int givenPosition, T newEntry){//在指定位置处插入结点
  52. boolean isSuccessful = true;
  53. if(givenPosition >= 1 && givenPosition <= length + 1){
  54. Node newNode = new Node(newEntry);
  55. if(isEmpty()){//表空为,插入某个元素
  56. firstNode = newNode;
  57. lastNode = newNode;
  58. }
  59. else if(givenPosition == 1){//表不空时,在第一个位置处插入元素
  60. newNode.next = firstNode;
  61. firstNode = newNode;
  62. }
  63. else if(givenPosition == length + 1){//表不空时,在最后一个位置处插入元素
  64. lastNode.next = newNode;
  65. lastNode = newNode;
  66. }
  67. else{//在其它位置插入结点
  68. Node nodeBefore = getNodeAt(givenPosition - 1);
  69. Node nodeAfter = nodeBefore.next;
  70. nodeBefore.next = newNode;
  71. newNode.next = nodeAfter;
  72. }
  73. length++;
  74. }
  75. else
  76. isSuccessful = false;
  77. return isSuccessful;
  78. }
  79.  
  80. @Override
  81. public final void clear() {//clear()在构造器中被调用了,所以此外用final修饰符
  82. firstNode = null;
  83. lastNode = null;
  84. length = 0;
  85. }
  86.  
  87. @Override
  88. public T remove(int givenPosition) {//删除指定位置处的结点
  89. T result = null;
  90. if((!isEmpty()) && ((givenPosition >= 1) && (givenPosition <= length))){
  91. if(givenPosition == 1){//删除第一个位置处的结点
  92. result = firstNode.data;
  93. firstNode = firstNode.next;
  94. if(length == 1)//链表中只有一个元素时,删除之后,尾指针为空
  95. lastNode = null;
  96. }
  97. else//删除表中其它位置结点
  98. {
  99. Node nodeBefore = getNodeAt(givenPosition - 1);
  100. Node nodeToRemove = nodeBefore.next;
  101. Node nodeAfter = nodeToRemove.next;
  102. nodeBefore.next = nodeAfter;
  103. result = nodeToRemove.data;
  104.  
  105. if(givenPosition == length)//当删除最后一个元素后,尾指针应指向其前一个元素
  106. lastNode = nodeBefore;
  107. }
  108. length--;
  109. }
  110. return result;
  111. }
  112.  
  113. @Override
  114. public boolean replace(int givenPosition, T newEntry) {//替换指定位置处结点的值
  115. boolean isSuccessful = true;
  116. if((!isEmpty()) && ((givenPosition >= 1) && (givenPosition <= length))){
  117. Node desireNode = getNodeAt(givenPosition);
  118. desireNode.data = newEntry;
  119. }
  120. else
  121. isSuccessful = false;
  122. return isSuccessful;
  123. }
  124.  
  125. @Override
  126. public T getEntry(int givenPosition) {//获取指定位置的结点的值
  127. T result = null;
  128. if((!isEmpty()) && ((givenPosition >= 1) && (givenPosition <= length))){
  129. result = getNodeAt(givenPosition).data;
  130. }
  131. return result;
  132. }
  133.  
  134. @Override
  135. public boolean contains(T anEntry) {//判断链表中的结点是否包含某个值
  136. boolean found = false;
  137. Node currentNode = firstNode;
  138. while(!found && currentNode != null){
  139. if(currentNode.data.equals(anEntry)){
  140. found = true;
  141. break;
  142. }
  143. currentNode = currentNode.next;
  144. }
  145. return found;
  146. }
  147.  
  148. @Override
  149. public int getLength() {//获取链表的长度
  150. return length;
  151. }
  152.  
  153. @Override
  154. public boolean isEmpty() {//判断链表是否为空
  155. boolean result;
  156. if(length == 0){
  157. assert firstNode == null;
  158. result = true;
  159. }
  160. else{
  161. assert firstNode != null;
  162. result = false;
  163. }
  164. return result;
  165. }
  166.  
  167. @Override
  168. public void display() {//遍历链表,显示链表中的每个结点的值
  169. Node currentNode = firstNode;
  170. while(currentNode != null){
  171. System.out.println(currentNode.data);
  172. currentNode = currentNode.next;
  173. }
  174. }
  175. }

JAVA单链表的实现-不带头结点但带有尾指针的更多相关文章

  1. JAVA单链表的实现-不带头结点且没有尾指针

    本程序采用JAVA语言实现了线性表的链式实现.首先定义了线性表的接口ListInterface,然后LList类实现了ListInterface完成了链表的实现. 本实现中,链表是不带表头结点的,且有 ...

  2. 【c++版数据结构】之循环单链表的实现(带头结点以及尾节点)

    所实现的循环单链表的结构例如以下图所看到的: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill ...

  3. java单链表常用操作

    总结提高,与君共勉 概述. 数据结构与算法亘古不变的主题,链表也是面试常考的问题,特别是手写代码常常出现,将从以下方面做个小结 [链表个数] [反转链表-循环] [反转链表-递归] [查找链表倒数第K ...

  4. Java单链表反转 详细过程

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/guyuealian/article/details/51119499 Java单链表反转 Java实 ...

  5. Java单链表反转图文详解

    Java单链表反转图文详解 最近在回顾链表反转问题中,突然有一些新的发现和收获,特此整理一下,与大家分享 背景回顾 单链表的存储结构如图: 数据域存放数据元素,指针域存放后继结点地址 我们以一条 N1 ...

  6. 求单链表倒数第m个结点

    问题:求单链表倒数第m个结点,要求不准求链表的长度,也不许对链表进行逆转 解:设置两个指针p和q,p.q指向第一个结点.让p先移动到链表的第m个结点,然后p和q同时向后移动,直到p首先到达尾结点.此时 ...

  7. java 单链表 练习

    练习一下java单链表的简单习题 package com.test1; import java.util.Stack; public class SingleListDemo { /** * 返回单链 ...

  8. Java单链表简单实现* @version 1.0

    package com.list; /** * 数据结构与算法Java表示 * @version 1.0 * @author 小明 * */ public class MyLinkedList { p ...

  9. 链表 | 递归删除不带头结点链表所有x元素

    王道P37 T1 : 设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点. 王道上的答案绝对是错的,我自己想了一个 函数主体 LinkList* del_x(LinkList* prior, ...

随机推荐

  1. win8和win7下解决php5.3和5.4、5.5等不能加载php_curl.dll的终极解决办法 收藏

    win8和win7下解决php5.3和5.4.5.5等不能加载php_curl.dll的终极解决办法 收藏2015年01月11日 最近分别在WIN7和Windows8 上分别安装php 高版本!都遇到 ...

  2. Android控件第6类——杂项控件

    1.Toast Toast用于显示提示信息. Toast不会获得焦点,没法关闭,过段时间会自动消失. 使用方法:Toast.makeText获得Toast,并设置相关属性.调用Toast对象的show ...

  3. 如何根据元素的className获取元素?

    getElementsByClassName()是HTML5 新增的DOM API.IE8以下不支持 我们知道,原生的方法,是getElementById()和getElementsByTagName ...

  4. ActiveMA在CentOS7下的安装

    下载:apache-activemq-5.14.0-bin.tar.gz http://activemq.apache.org/activemq-5157-release.html Getting t ...

  5. BZOJ2959长跑——LCT+并查集(LCT动态维护边双连通分量)

    题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前. 为 ...

  6. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  7. PHP Switch 语句判断成绩

    初入PHP,就想简单的利用switch语句写一个关于成绩等级的判断,整个过程分为两部分一是前端数据,二是后台的计算. [HTML代码] <!-- * * * @Author: wyy * @Da ...

  8. 注册页面手机验证码无跳转接收[html+js+ajax+php]

    [学习笔记] 来源:注册时需要使用短信验证码,但是注册的时候,点击接收验证码时,会产生跳转(尼玛,这不是我想要的啊!o(╥﹏╥)o) 查询资料和看书之后,知道使用js+ajax可以实现,就从网上找了一 ...

  9. LOJ #2540. 「PKUWC 2018」随机算法(概率dp)

    题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...

  10. TensorFlow分布式计算机制解读:以数据并行为重

    Tensorflow 是一个为数值计算(最常见的是训练神经网络)设计的流行开源库.在这个框架中,计算流程通过数据流程图(data flow graph)设计,这为更改操作结构与安置提供了很大灵活性.T ...