JAVA单链表的实现-不带头结点但带有尾指针
1,本程序实现了线性表的链式存储结构。实现的链表带有两个指针,一个始终指向链表中的第一个结点,另一个指针始终指向链表中的最后一个结点。
之所以设置尾指针,是因为,在插入元素到链表中的末尾时,可以通过尾指针直接找到链表的最后一个元素,从而不需要遍历链表就可以完成插入操作。
2,具体实现链表的类名为LList2.java,它首先实现了线性表的接口ListInterface,该接口的定义见:http://www.cnblogs.com/hapjin/p/4549492.html
LList2.java的代码 如下:
- public class LList2<T> implements ListInterface<T>{
- private Node firstNode;//指向第一个结点的指针,该链表是不带头结点的单链表
- private Node lastNode;//尾指针,指向链表中的最后一个结点
- private int length;//表示单链表的长度
- //Node类中不需要定义访问属性的get方法以及set方法,因为Node是内部类,内部类的属性可以直接在外部类中被访问
- class Node{
- //Node是内部类,其外部类中已经定义了T,故可以在这里使用通配符T
- private T data;//结点的数据部分
- private Node next;//结点的指针部分,指向下一个结点
- //Node类中不需要默认构造器
- public Node(T dataPortion){
- data = dataPortion;
- }
- public Node(T dataPortion, Node nextNode){
- data = dataPortion;
- next = nextNode;
- }
- }
- public LList2(){
- clear();
- }
- //获取链表中指定位置处的结点
- private Node getNodeAt(int givenPosition){
- assert (!isEmpty() && ((1 <= givenPosition) && (givenPosition <= length)));
- Node currentNode = firstNode;
- for(int counter = 1; counter < givenPosition; counter++){
- currentNode = currentNode.next;
- }
- assert currentNode != null;
- return currentNode;
- }
- @Override
- public boolean add(T newEntry) {
- Node newNode = new Node(newEntry);
- if(isEmpty()){//插入第一个结点
- firstNode = newNode;
- }
- else{//在其它位置插入结点
- lastNode.next = newNode;
- }
- lastNode = newNode;
- length++;
- return true;
- }
- @Override
- public boolean add(int givenPosition, T newEntry){//在指定位置处插入结点
- boolean isSuccessful = true;
- if(givenPosition >= 1 && givenPosition <= length + 1){
- Node newNode = new Node(newEntry);
- if(isEmpty()){//表空为,插入某个元素
- firstNode = newNode;
- lastNode = newNode;
- }
- else if(givenPosition == 1){//表不空时,在第一个位置处插入元素
- newNode.next = firstNode;
- firstNode = newNode;
- }
- else if(givenPosition == length + 1){//表不空时,在最后一个位置处插入元素
- lastNode.next = newNode;
- lastNode = newNode;
- }
- else{//在其它位置插入结点
- Node nodeBefore = getNodeAt(givenPosition - 1);
- Node nodeAfter = nodeBefore.next;
- nodeBefore.next = newNode;
- newNode.next = nodeAfter;
- }
- length++;
- }
- else
- isSuccessful = false;
- return isSuccessful;
- }
- @Override
- public final void clear() {//clear()在构造器中被调用了,所以此外用final修饰符
- firstNode = null;
- lastNode = null;
- length = 0;
- }
- @Override
- public T remove(int givenPosition) {//删除指定位置处的结点
- T result = null;
- if((!isEmpty()) && ((givenPosition >= 1) && (givenPosition <= length))){
- if(givenPosition == 1){//删除第一个位置处的结点
- result = firstNode.data;
- firstNode = firstNode.next;
- if(length == 1)//链表中只有一个元素时,删除之后,尾指针为空
- lastNode = null;
- }
- else//删除表中其它位置结点
- {
- Node nodeBefore = getNodeAt(givenPosition - 1);
- Node nodeToRemove = nodeBefore.next;
- Node nodeAfter = nodeToRemove.next;
- nodeBefore.next = nodeAfter;
- result = nodeToRemove.data;
- if(givenPosition == length)//当删除最后一个元素后,尾指针应指向其前一个元素
- lastNode = nodeBefore;
- }
- length--;
- }
- return result;
- }
- @Override
- public boolean replace(int givenPosition, T newEntry) {//替换指定位置处结点的值
- boolean isSuccessful = true;
- if((!isEmpty()) && ((givenPosition >= 1) && (givenPosition <= length))){
- Node desireNode = getNodeAt(givenPosition);
- desireNode.data = newEntry;
- }
- else
- isSuccessful = false;
- return isSuccessful;
- }
- @Override
- public T getEntry(int givenPosition) {//获取指定位置的结点的值
- T result = null;
- if((!isEmpty()) && ((givenPosition >= 1) && (givenPosition <= length))){
- result = getNodeAt(givenPosition).data;
- }
- return result;
- }
- @Override
- public boolean contains(T anEntry) {//判断链表中的结点是否包含某个值
- boolean found = false;
- Node currentNode = firstNode;
- while(!found && currentNode != null){
- if(currentNode.data.equals(anEntry)){
- found = true;
- break;
- }
- currentNode = currentNode.next;
- }
- return found;
- }
- @Override
- public int getLength() {//获取链表的长度
- return length;
- }
- @Override
- public boolean isEmpty() {//判断链表是否为空
- boolean result;
- if(length == 0){
- assert firstNode == null;
- result = true;
- }
- else{
- assert firstNode != null;
- result = false;
- }
- return result;
- }
- @Override
- public void display() {//遍历链表,显示链表中的每个结点的值
- Node currentNode = firstNode;
- while(currentNode != null){
- System.out.println(currentNode.data);
- currentNode = currentNode.next;
- }
- }
- }
JAVA单链表的实现-不带头结点但带有尾指针的更多相关文章
- JAVA单链表的实现-不带头结点且没有尾指针
本程序采用JAVA语言实现了线性表的链式实现.首先定义了线性表的接口ListInterface,然后LList类实现了ListInterface完成了链表的实现. 本实现中,链表是不带表头结点的,且有 ...
- 【c++版数据结构】之循环单链表的实现(带头结点以及尾节点)
所实现的循环单链表的结构例如以下图所看到的: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill ...
- java单链表常用操作
总结提高,与君共勉 概述. 数据结构与算法亘古不变的主题,链表也是面试常考的问题,特别是手写代码常常出现,将从以下方面做个小结 [链表个数] [反转链表-循环] [反转链表-递归] [查找链表倒数第K ...
- Java单链表反转 详细过程
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/guyuealian/article/details/51119499 Java单链表反转 Java实 ...
- Java单链表反转图文详解
Java单链表反转图文详解 最近在回顾链表反转问题中,突然有一些新的发现和收获,特此整理一下,与大家分享 背景回顾 单链表的存储结构如图: 数据域存放数据元素,指针域存放后继结点地址 我们以一条 N1 ...
- 求单链表倒数第m个结点
问题:求单链表倒数第m个结点,要求不准求链表的长度,也不许对链表进行逆转 解:设置两个指针p和q,p.q指向第一个结点.让p先移动到链表的第m个结点,然后p和q同时向后移动,直到p首先到达尾结点.此时 ...
- java 单链表 练习
练习一下java单链表的简单习题 package com.test1; import java.util.Stack; public class SingleListDemo { /** * 返回单链 ...
- Java单链表简单实现* @version 1.0
package com.list; /** * 数据结构与算法Java表示 * @version 1.0 * @author 小明 * */ public class MyLinkedList { p ...
- 链表 | 递归删除不带头结点链表所有x元素
王道P37 T1 : 设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点. 王道上的答案绝对是错的,我自己想了一个 函数主体 LinkList* del_x(LinkList* prior, ...
随机推荐
- 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 高版本!都遇到 ...
- Android控件第6类——杂项控件
1.Toast Toast用于显示提示信息. Toast不会获得焦点,没法关闭,过段时间会自动消失. 使用方法:Toast.makeText获得Toast,并设置相关属性.调用Toast对象的show ...
- 如何根据元素的className获取元素?
getElementsByClassName()是HTML5 新增的DOM API.IE8以下不支持 我们知道,原生的方法,是getElementById()和getElementsByTagName ...
- ActiveMA在CentOS7下的安装
下载:apache-activemq-5.14.0-bin.tar.gz http://activemq.apache.org/activemq-5157-release.html Getting t ...
- BZOJ2959长跑——LCT+并查集(LCT动态维护边双连通分量)
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前. 为 ...
- BZOJ3862Little Devil I——树链剖分+线段树
题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...
- PHP Switch 语句判断成绩
初入PHP,就想简单的利用switch语句写一个关于成绩等级的判断,整个过程分为两部分一是前端数据,二是后台的计算. [HTML代码] <!-- * * * @Author: wyy * @Da ...
- 注册页面手机验证码无跳转接收[html+js+ajax+php]
[学习笔记] 来源:注册时需要使用短信验证码,但是注册的时候,点击接收验证码时,会产生跳转(尼玛,这不是我想要的啊!o(╥﹏╥)o) 查询资料和看书之后,知道使用js+ajax可以实现,就从网上找了一 ...
- LOJ #2540. 「PKUWC 2018」随机算法(概率dp)
题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...
- TensorFlow分布式计算机制解读:以数据并行为重
Tensorflow 是一个为数值计算(最常见的是训练神经网络)设计的流行开源库.在这个框架中,计算流程通过数据流程图(data flow graph)设计,这为更改操作结构与安置提供了很大灵活性.T ...