Java线性表——双链表实现

双向链表的节点结构,双向链表不但可以访问后面的数据,还可以访问前面的数据

pre date next

1.节点接口定义

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

	//删除节点时起关键作用
	public Node getNext();
	
}

2.双向链表接口定义

public class DLNode implements Node{

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

	public DLNode getPre() {
		return pre;
	}

	public void setPre(DLNode pre) {
		this.pre = pre;
	}

	public void setNext(DLNode next) {
		this.next = next;
	}

	public DLNode getNext() {
		return next;
	}

	
	@Override
	public Object getData() {
		return element;
	}

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


}

3.链接表接口

public interface LinkedList {
	
	//返回线性表的大小,即数据元素的个数
	public int getSize();
	
	//判断线性表是否为空
	public boolean isEmploy();
	
	//返回第一个节点
	public Node first() throws OutOfBoundaryException;
	
	//返回最后一个节点
	public Node last() throws OutOfBoundaryException;
	
	//返回p之前的节点
	public Node getPre(Node p) throws InvalidNodeException,OutOfBoundaryException;
	
	//返回p之后的节点
	public Node getNext(Node p) throws InvalidNodeException,OutOfBoundaryException;
	
	//将e作为第一个元素插入链接表,并返回e所在的节点
	public Node insertFirst(Object e);
	
	//将e作为最后一个元素插入链接表,并返回e所在的节点
	public Node insertLast(Object e);
	
	//将e插入到节点p之前的位置,并且返回e的节点位置
	public Node insertBefor(Node p,Object e) throws InvalidNodeException;
	
	//将e插入到节点p之后的位置,并且返回e的节点位置
	public Node insertAfter(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 Object get(int i)throws OutOfBoundaryException;
	
	//迭代器
	public Iterator element();
}

4.定义异常

/*
 * 结点在以下情况下是不合法的
 * 		p=null
 * 		p在链表中不存在
 * 		在调用方法getPre(p)的时候,p是第一个存数据的节点
 * 		在调用方法getNext(p)的时候,p是最后一个存数据的节点
 */
public class InvalidNodeException extends RuntimeException{
	public InvalidNodeException(String err){
		super(err);
	}
}
/*
 * 越界异常
 */
public class OutOfBoundaryException extends RuntimeException{

	public OutOfBoundaryException(String err){
		super(err);
	}
}

5.基于双向链接表实现的链接表

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);
		head.setPre(head);
	}

	/*
	 * 辅助方法,判断节点p是否合法
	 */
	protected DLNode checkPosition(Node p) throws InvalidNodeException {
		if (p == null)
			throw new InvalidNodeException("老刁,节点是空的GG");
		if (p == head)
			throw new InvalidNodeException("老刁,节点指向了我的头了GG");
		if (p == tail)
			throw new InvalidNodeException("小刁,节点指向了我的尾巴了GG");
		DLNode node = (DLNode) p;
		return node;
	}

	/*
	 * 链表的大小
	 */
	public int getSize() {
		return size;
	}

	/*
	 * 链表是否为空
	 */
	public boolean isEmploy() {
		return size == 0;
	}

	/*
	 * 返回第一个节点
	 */
	public Node first() throws OutOfBoundaryException {
		if (isEmploy())
			throw new OutOfBoundaryException("链表为空,怎么访问节点");
		return head.getNext();
	}

	/*
	 * 返回最后一个节点
	 */
	public Node last() throws OutOfBoundaryException {
		if (isEmploy())
			throw new OutOfBoundaryException("链表为空,怎么访问节点");
		return tail.getPre();
	}

	/*
	 * 返回p之前的节点
	 */
	public Node getPre(Node p) throws InvalidNodeException, OutOfBoundaryException {
		DLNode node = checkPosition(p);
		node = node.getPre();
		if (node == head)
			throw new OutOfBoundaryException("小伙子,欢迎来到头节点,可我没有东西招待你");
		return node;
	}

	/*
	 * 返回p之后的节点
	 */
	public Node getNext(Node p) throws InvalidNodeException, OutOfBoundaryException {
		DLNode node = checkPosition(p);
		node = node.getNext();
		if (node == tail)
			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作为最后一个元素插入到链表
	 */
	public Node insertLast(Object e) {
		DLNode node = new DLNode(e, tail.getPre(), tail);
		tail.getPre().setNext(node);
		tail.setPre(node);
		size++;
		return node;
	}

	/*
	 * 将e插入到节点p之前的位置,并且返回e的节点位置
	 */
	public Node insertBefor(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;
	}

	/*
	 * 将e插入到节点p之后的位置,并且返回e的节点位置
	 */
	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);
		node.setNext(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;
	}

	/*
	 * 删除首元素
	 */
	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 element() {

		return new LinkedListIterator(this);
	}

	/*
	 * 遍历双向链表
	 */
	public void print() {
		DLNode temp = (DLNode) head;
		while (temp != null) {
			System.out.print(temp.getData() + ",");
			temp = (DLNode) temp.getNext();
		}
		System.out.println();
		//
	}

	/*
	返回指定位置上的元素
	 */
	public Object get(int i) {
		if(i<0 || i>size)
			throw new OutOfBoundaryException("别再让我看见你越界");
		
		return null;
	}
}

6.迭代器接口

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

如果代码有什么问题请大家在评论区留言,谢谢,再说一句,写代码这东西还是要多练!

猜你喜欢

转载自blog.csdn.net/qiuxue4mz/article/details/82791966