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;
        }
    }
}
时间: 2024-10-14 19:31:14

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

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

本程序采用JAVA语言实现了线性表的链式实现.首先定义了线性表的接口ListInterface,然后LList类实现了ListInterface完成了链表的实现. 本实现中,链表是不带表头结点的,且有一个指针始终指向链表中的第一个元素,并没有定义尾指针.因此,每次向链表中插入新结点时需要遍历链表一次. 更详细的解释参考<数据结构与算法分析 JAVA语言描述第二版>Frank M. Carrano 著 ListInterface接口的定义如下: public interface ListInte

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

所实现的循环单链表的结构如下图所示: 循环单链表的实现,和上一篇文章单链表的实现大致相同点击打开链接,略有区别: 1:循环判断的条件不再是s == NULL或者s->next == NULL,而是他们是否等于头指针.2: 断开链表时的处理,尾节点的next不是NULL,而是指向头结点 具体细节参考上一篇文章 头文件:SCList.h #ifndef SCLIST_H #define SCLIST_H #include<iostream> #include<cassert> u

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

所实现的单链表的结构如下图所示: 头文件:SList.h #include<iostream> #include<cassert> using namespace std; typedef enum{FALSE,TRUE}Status; template<class Type> class List; template<class Type> class ListNode { friend class List<Type>; //友元类可以访问该

【LeetCode-面试算法经典-Java实现】【083-Remove Duplicates from Sorted List(排序的单链表中删除重复的结点)】

[083-Remove Duplicates from Sorted List(排序的单链表中删除重复的结点)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given a sorted linked list, delete all duplicates such that each element appear only once. For example, Given 1->1->2, return 1->2. Given 1->1->2

java 单链表的实现

package liaobiao;//链表测试public class Node { private int value; private Node next; //存放下一个节点的指针 //构造方法,进行传参 public Node(int value){ this.value = value; } public Node(){ } //像链表的尾部加入元素,需要先找到最后一个节点 public void addNode(Node n ){ //需要先找到最后一个节点 Node node =t

java单链表常用操作

总结提高,与君共勉 概述. 数据结构与算法亘古不变的主题,链表也是面试常考的问题,特别是手写代码常常出现,将从以下方面做个小结 [链表个数] [反转链表-循环] [反转链表-递归] [查找链表倒数第K个节点] [查找链表中间节点] [判断链表是否有环] [从尾到头打印单链表-递归] [从尾到头打印单链表-栈] [由小到大合并有序单链表-循环] [由小到大合并有序单链表-递归] 通常在java中这样定义单链表结构 <span style="font-family:Microsoft YaHe

Java单链表、双端链表、有序链表实现

Java单链表.双端链表.有序链表实现 原创 2014年03月31日 23:45:35 标签: Java / 单链表 / 双端链表 / 有序链表 65040 单链表: insertFirst:在表头插入一个新的链接点,时间复杂度为O(1) deleteFirst:删除表头的链接点,时间复杂度为O(1) 有了这两个方法,就可以用单链表来实现一个栈了,见http://blog.csdn.net/a19881029/article/details/22579759 find:查找包含指定关键字的链接点

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

王道P37 T1 : 设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点. 王道上的答案绝对是错的,我自己想了一个 函数主体 LinkList* del_x(LinkList* prior,LinkList* L,int x){ if(L==NULL) return NULL; if(L->data==x){ if(prior==NULL){ LinkList* ans=L->next; delete L; if(ans!=NULL) ans=del_x(NULL,ans,x); /

java单链表

单链表 一.单链表的概念 链表是最基本的数据结构,其存储的你原理图如下图所示 上面展示的是一个单链表的存储原理图,简单易懂,head为头节点,他不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用,而每个节点中都有一个next引用,指向下一个节点,就这样一节一节往下面记录,直到最后一个节点,其中的next指向null. 链表有很多种,比如单链表,双链表等等.我们就对单链表进行学习,其他的懂了原理其实是一样的. 二.用java实现单链表 语言只是一种工具,数据结构真正体会的是那种