Java线性表——单链表实现

这是单链表的节点结构,大家应该对单链表有一些了解,我就不多说了,直接撸代码吧

data

next

1.节点接口

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

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

2.单链表接口定义

public class SLNode implements Node{

	private Object element;
	private Node next;
	

	public SLNode() {
		this(null,null);
	}

	public SLNode(Object element, Node next) {
		this.element = element;
		this.next = next;
	}

	public Node getNext() {
		return next;
	}

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

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

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

}

3.抽象的List接口

public interface List {
	
	//返回线性表的大小,即数据元素的个数
	public int getSize();
	
	//判断线性表是否为空
	public boolean isEmploy();
	
	//判断线性表是否包含元素e
	public boolean contains(Object se);
	
	//返回数据元素e在线性表中的序号,若不存在返回-1
	public int indexOf(Object e);
	
	//将数据元素e插入到线性表的i个位置,越界则报错
	public void insert(int i,Object e) throws OutOfBoundaryException;
	
	//将数据元素e插入到元素obj之前
	public boolean insertBefor(Object obj,Object e);
	
	//将数据元素插入到元素obj之后
	public boolean insertAfter(Object obj,Object e);
	
	//删除线性表中序号为i的元素,成功则返回这个元素,i越界报错
	public Object remove(int i) throws OutOfBoundaryException;
	
	//删除线性表中第一个与元素e相同的元素,成功true ,失败flase
	public boolean remove(Object e);
	
	//替换线性表中序号为i的元素e,成功则返回原数据,i越界报错
	public Object replace(int i,Object e) throws OutOfBoundaryException;
	
	//返回线性表中序号为i的元素,i越界报错
	public Object get(int i) throws OutOfBoundaryException;
}

4.线性表单链表的实现

public class ListSLinked implements List {

	// 数据元素的比较策略(这我没自己写,我用的是系统的equal和compare)

	// 首节点引用
	private SLNode head;

	// 元素个数
	private int size;

	// public ListSLinked() {
	// }

	public ListSLinked() {
		// this.size = size;
		head = new SLNode();
	}

	/*
	 * 辅助方法,获取元素e所在节点的前驱节点
	 */
	private SLNode getPreNode(Object e) {
		SLNode p = head;// 定义p为第一个头节点的前驱
		while (p.getNext() != null)// 只要还没到最后一个元素就继续找
			if (e.equals(p.getNext().getData()))// 检查元素线性表中是否有元素e
				return p;// 如果找到了就返回这个元素的节点先驱
			else
				p = (SLNode) p.getNext();// 否则就继续找
		return null;// 如果一直没找到就返回null
	}

	/*
	 * 辅助方法:根据序号获取前驱节点
	 */
	private SLNode getPreNode(int i) {
		SLNode p = head;
		for (; i > 0; i--)
			p = (SLNode) p.getNext();
		return p;
	}

	/*
	 * 获取序号为i的元素所在节点
	 */
	private SLNode getNode(int i) {
		SLNode p = (SLNode) head.getNext();
		for (; i > 0; i--)// 为什么不用 i=1;i<size;i++
			p = (SLNode) p.getNext();
		return p;
	}

	/*
	 * 线性表元素个数
	 */
	public int getSize() {
		return size;
	}

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

	/*
	 * 查看线性表中是否有元素se
	 */
	public boolean contains(Object se) {
		SLNode p = (SLNode) head.getNext();
		while (p != null)
			if (se.equals(p.getData()))
				return true;
			else
				p = (SLNode) p.getNext();
		return false;
	}

	/*
	 * 按元素查找序列号
	 */
	public int indexOf(Object e) {
		SLNode p = (SLNode) head.getNext();
		int index = 0;
		while(p!=null){
			if(e.equals(p.getData())){
				return index;
			}else{
				index++;
				p = (SLNode) p.getNext();
			}
		}
		return -1;
	}

	/*
	 * 插入数据(尾插法)
	 */
	public void insert(int i, Object e) throws OutOfBoundaryException {

		if (i < 0 || i > size)
			throw new OutOfBoundaryException("sorry,您输入的序号越界");
		SLNode p = getPreNode(i);
		SLNode q = new SLNode(e, p.getNext());
		p.setNext(q);
		size++;
		return;
	}

	/*
	 * 将元素e插入到obj之前(不是头插法)
	 */
	public boolean insertBefor(Object obj, Object e) {
		SLNode p = getPreNode(obj);
		if (p != null) {
			SLNode q = new SLNode(e, p.getNext());
			p.setNext(q);
			size++;
			return true;
		}
		return false;
	}

	/*
	 * 将元素e插入到obj之后
	 */
	public boolean insertAfter(Object obj, Object e) {
		// 第一种方法
		// SLNode p = (SLNode) getPreNode(obj).getNext();
		// if(p!=null){
		// SLNode q = new SLNode(e,p.getNext());
		// p.setNext(q);
		// size++;
		// return true;
		// }
		// return false;
		SLNode p = (SLNode) head.getNext();
		if (obj.equals(p.getData())) {
			SLNode q = new SLNode(e, p.getNext());
			p.setNext(q);
			size++;
			return true;
		} else
			p = (SLNode) p.getNext();
		return false;
	}

	/*
	 * 根据序号删除元素,并返回原元素
	 */
	public Object remove(int i) throws OutOfBoundaryException {
		if (i < 0 || i > size)
			throw new OutOfBoundaryException("hi boy,your sanner is error");
		SLNode p = getPreNode(i);
		Object obj = p.getNext().getData();
		p.setNext(p.getNext().getNext());// 应该这样写p.setNext(p.getNext().getNext)
		size--;
		return obj;
	}

	/*
	 * 删除第一个与输入的元素相同的数
	 */
	public boolean remove(Object e) {
		SLNode p = getPreNode(e);
		if (p != null) {
			p.setNext(p.getNext().getNext());
			size--;
			return true;
		}
		return false;
	}

	/*
	 * 将序号为i中的元素替换为e,并返回原元素
	 */
	public Object replace(int i, Object e) throws OutOfBoundaryException {
		if (i < 0 || i > size)
			throw new OutOfBoundaryException("大兄弟,别再越界了");
		SLNode p = getPreNode(i);
		SLNode q = new SLNode(e,p.getNext().getNext());
		p.setNext(q);
		Object obj = p.getNext().getData();
			return obj;
	}

	/*
	根据序号获取该元素
	 */
	public Object get(int i) throws OutOfBoundaryException {
		if(i<0 || i>size)
			throw new OutOfBoundaryException("亲,别让我再处理越界了,好吗");
		SLNode p = getPreNode(i);
		Object obj = p.getNext().getData();
		return obj;
	}

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

5.自己定义的异常

/*
 *越界异常
/*
public class OutOfBoundaryException extends RuntimeException{

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

测试类我就不写了,大家自己写吧,还有我的程序有小bug希望你们能解决,然后在评论区留言给我,谢谢!

猜你喜欢

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