数据结构之基于Java的链接列表实现

本文的代码来自于《数据结构与算法(JAVA语言版)》,是笔者在网上找到的资料,非正式出刊版物。笔者对代码一些比较难以理解的部分添加了注释和图解,欢迎大家来讨论。
双链表实现结构图
基于Java的数据结构之双向链表实现的链接表片描述

public class LinkedListDLNode implements LinkedList {
    private int size;   //规模
    private DLNode head;//头结点,哑元结点
    private DLNode tail;//尾结点,哑元结点
    public LinkedListDLNode() {
        size = 0;
        head = new DLNode();//构建只有头尾结点的链表
        tail = new DLNode();
        head.setNext(tail);
        tail.setPre(head);
    }
    //辅助方法,判断结点p是否合法,如合法转换为DLNode
    private DLNode checkPosition(Node p) throws InvalidNodeException {
        if (p==null)
            throw new InvalidNodeException("错误:p为空。");
        if (p==head)
            throw new InvalidNodeException("错误:p指向头节点,非法。");
        if (p==tail)
            throw new InvalidNodeException("错误:p指向尾结点,非法。");
        DLNode node = (DLNode)p;
        return node;
    }

    //查询链接表当前的规模
    public int getSize() {
        return size;
    }

    //判断链接表是否为空
    public boolean isEmpty() {
        return size==0;
    }

    //返回第一个结点
    public Node first() throws OutOfBoundaryException{
        if (isEmpty())
            throw new OutOfBoundaryException("错误:链接表为空。");
        return head.getNext();
    }

    //返回最后一结点
    public Node last() throws OutOfBoundaryException{
        if (isEmpty())
            throw new OutOfBoundaryException("错误:链接表为空。");
        return tail.getPre();
    }

    //返回p之后的结点
    public Node getNext(Node p) throws InvalidNodeException, OutOfBoundaryException {
        DLNode node = checkPosition(p);
        node = node.getNext();
        if (node==tail)
            throw new OutOfBoundaryException("错误:已经是链接表尾端。");
        return node;
    }

    //返回p之前的结点
    public Node getPre(Node p) throws InvalidNodeException, OutOfBoundaryException {
        DLNode node = checkPosition(p);
        node = node.getPre();
        if (node==head)
            throw new OutOfBoundaryException("错误:已经是链接表前端。");
        return node;
    }

    //将e作为第一个元素插入链接表
    public Node insertFirst(Object e) {
        DLNode node = new DLNode(e,head,head.getNext());
        head.getNext().setPre(node);
        head.setNext(node);
        size++;
        return node;
    }

    //将e作为最后一个元素插入列表,并返回e所在结点
    public Node insertLast(Object e) {
        DLNode node = new DLNode(e,tail.getPre(),tail);
        tail.getPre().setNext(node);
        tail.setPre(node);
        size++;
        return node;
    }

    public Node insertAfter(Node p, Object e) throws InvalidNodeException {
        DLNode node = checkPosition(p);
        DLNode newNode = new DLNode(e,node,node.getNext());
        node.getNext().setPre(newNode);//将q节点的前驱设置成e节点
        node.setNext(newNode);//将p节点的后驱设置成e节点
        size++;
        return newNode;
    }//将e插入至p之后的位置,并返回e所在结点

基于Java的数据结构之双向链表实现的链接表

    //将e插入至p之前的位置,并返回e所在结点
    public Node insertBefore(Node p, Object e) throws InvalidNodeException {
        DLNode node = checkPosition(p);
        DLNode newNode = new DLNode(e,node.getPre(),node);
        node.getPre().setNext(newNode);
        node.setPre(newNode);
        size++;
        return newNode;
    }

    public Object remove(Node p) throws InvalidNodeException {
        DLNode node = checkPosition(p);
        Object obj = node.getData();
        node.getPre().setNext(node.getNext());
        node.getNext().setPre(node.getPre());
        size--;
        return obj;
    }//删除给定位置处的元素,并返回之

基于Java的数据结构之双向链表实现的链接表

    //删除首元素,并返回之
    public Object removeFirst() throws OutOfBoundaryException{
        return remove(head.getNext());
    }

    //删除末元素,并返回之
    public Object removeLast() throws OutOfBoundaryException{
        return remove(tail.getPre());
    }

    //将处于给定位置的元素替换为新元素,并返回被替换的元素
    public Object replace(Node p, Object e) throws InvalidNodeException {
        DLNode node = checkPosition(p);
        Object obj = node.getData();
        node.setData(e);
        return obj;
    }

    //元素迭代器
    public Iterator elements() {
        return new LinkedListIterator(this);
    }   
}


----------


public interface LinkedList {
//查询链接表当前的规模
public int getSize();
//判断链接表是否为空
public boolean isEmpty();
//返回第一个结点
public Node first() throws OutOfBoundaryException;
//返回最后一结点
public Node last() throws OutOfBoundaryException;
//返回p之后的结点
public Node getNext(Node p) throws InvalidNodeException, OutOfBoundaryException;
//返回p之前的结点
public Node getPre(Node p) throws InvalidNodeException, OutOfBoundaryException;
//将e作为第一个元素插入链接表,并返回e所在结点
public Node insertFirst(Object e);
//将e作为最后一个元素插入列表,并返回e所在结点
public Node insertLast(Object e);
//将e插入至p之后的位置,并返回e所在结点
public Node insertAfter(Node p, Object e) throws InvalidNodeException;
//将e插入至p之前的位置,并返回e所在结点
public Node insertBefore(Node p, Object e) throws InvalidNodeException;
//删除给定位置处的元素,并返回之
public Object remove(Node p) throws InvalidNodeException;
//删除首元素,并返回之
public Object removeFirst() throws OutOfBoundaryException;
//删除末元素,并返回之
public Object removeLast() throws OutOfBoundaryException;
//将处于给定位置的元素替换为新元素,并返回被替换的元素
public Object replace(Node p, Object e) throws InvalidNodeException;
//元素迭代器
public Iterator elements();
}

public interface Node {
    //获取结点数据域
    public Object getData();
    //设置结点数据域
    public void setData(Object obj);
}

public class DLNode implements Node {
    private Object element;
    private DLNode pre;
    private DLNode next;

    public DLNode() {
        this(null,null,null);
    }
    public DLNode(Object ele, DLNode pre, DLNode next){
        this.element = ele;
        this.pre = pre;
        this.next = next;
    }

    public DLNode getNext(){
        return next;
    }
    public void setNext(DLNode next){
        this.next = next;
    }
    public DLNode getPre(){
        return pre;
    }
    public void setPre(DLNode pre){
        this.pre = pre;
    }
    /****************Node Interface Method**************/
    public Object getData() {
        return element;
    }

    public void setData(Object obj) {
        element = obj;
    }   
}

public interface Iterator {
    //移动到第一个元素
    public void first();
    //移动到下一个元素
    public void next();
    //检查迭代器中是否还有剩余的元素
    public boolean isDone();
    //返回当前元素
    public Object currentItem();
}

public class LinkedListIterator implements Iterator {
    private LinkedList list;//链接表
    private Node current;//当前结点

    //构造方法
    public LinkedListIterator(LinkedList list) {
        this.list = list;
        if (list.isEmpty())     //若列表为空
            current = null;     //则当前元素置空
        else
            current = list.first();//否则从第一个元素开始
    }

    //移动到第一个元素
    public void first(){
        if (list.isEmpty())     //若列表为空
            current = null;     //则当前元素置空
        else
            current = list.first();//否则从第一个元素开始     
    }

    //移动到下一个元素
    public void next() throws OutOfBoundaryException{
        if (isDone()) 
            throw new OutOfBoundaryException("错误:已经没有元素。");
        if (current==list.last()) current = null;
        else current = list.getNext(current);
    }

    //检查迭代器中是否还有剩余的元素
    public boolean isDone() { return current==null; }

    //返回当前元素
    public Object currentItem() throws OutOfBoundaryException{
        if (isDone()) 
            throw new OutOfBoundaryException("错误:已经没有元素。");
        return current.getData();
    }
}

public class InvalidNodeException extends RuntimeException {
    public InvalidNodeException(String err) {
        super(err);
    }   
}

public class OutOfBoundaryException extends RuntimeException{

    public OutOfBoundaryException(String err){
        super(err);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值