先定义List接口,再编写SingleLinkedList类实现List接口,注意:真正的LinkedList底层使用双向链表实现的,这里只是用单链表模拟实现。
package com.qianyu.dataStructure.lineTable;
/**
* @author lijing
* @date 2019-03-19-19:38
* @discroption 模拟List接口
*/
public interface List {
//返回线性表的大小
public int size();
//返回线性表中序号为i的数据元素
public Object get(int i);
//如果线性表为空则返回true,否则返回false
public boolean isEmpty();
//判断线性表是否包含元素e
public boolean contains(Object e);
//返回数据元素e在线性表中的序号
public int indexOf(Object e);
//建数据元素e插入到线性表中第i个位置
public void add(int i,Object e);
//将数据元素e插入到线性表的末尾
public void add(Object e);
//删除集合中序号为i的元素,并返回之
public Object remove(int i);
//删除集合中第一个与e相同的元素
public boolean remove(Object e);
//替换集合中序号为i的数据元素为e,返回数据元素
public Object replace(int i,Object e);
}
自定义异常MyIndexOutOfBoundsException,表示非法索引异常
package com.qianyu.dataStructure.lineTable;
/**
* @author lijing
* @date 2019-03-19-20:34
* @discroption 自定义异常
*/
public class MyIndexOutOfBoundsException extends RuntimeException{
public MyIndexOutOfBoundsException() {
super();
}
public MyIndexOutOfBoundsException(String message) {
super(message);
}
}
自定义Node
结点类:
package com.qianyu.dataStructure.lineTable;
/**
* @author lijing
* @date 2019-03-21-20:38
* @discroption 用来表示单链表中一个结点
*/
public class Node {
/**
* 为了方便使用,将Node类中的属性设置为public
*/
public Object data;//存储数据
public Node next;//存储下一个结点的引用
public Node() {
}
public Node(Object data) {
this.data = data;
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
}
SingleLinkedList代码:
package com.qianyu.dataStructure.lineTable;
/**
* @author lijing
* @date 2019-03-21-20:37
* @discroption 用单链表模拟LinkedList,注意这里只是模拟,真正的LinkedList底层用的双向链表
*/
public class SingleLinkedList implements List {
private Node head = new Node();//头结点,不存储数据,为了编程方便
private int size;//表示SingleLinkedList的长度
@Override
public int size() {
return size;
}
@Override
public Object get(int i) {
//判断是否索引越界
if (i < 0 || i >= this.size) {
throw new MyIndexOutOfBoundsException("非法索引:" + i);
}
//遍历链表
Node p = this.head.next;
for (int j = 0; j < i; j++) {
p = p.next;
}
return p.data;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public boolean contains(Object e) {
return indexOf(e) >= 0;
}
@Override
public int indexOf(Object e) {
//第一个储存数据的结点是head的下一个结点
Node p = this.head.next;
if (e == null) {
for (int i = 0; i < this.size; i++) {
if (e == null) {
return i;
}
p = p.next;
}
} else {
for (int i = 0; i < this.size; i++) {
if (p.data.equals(e)) {
return i;
}
p = p.next;
}
}
return -1;
}
@Override
public void add(int i, Object e) {
//判断索引是否越界
if (i < 0 || i > this.size) {
throw new MyIndexOutOfBoundsException("非法索引:" + i);
}
//1.找到索引为i-1的结点
Node p = this.head;
for (int j = 0; j < i; j++) {
p = p.next;
}
//2.新建一个结点newNode,储存对象e
Node newNode = new Node();
newNode.data = e;
//3.将newNode结点的next指向索引为i-1的结点的下一个节点(即索引值为i的结点)
newNode.next = p.next;
//4.将索引为i-1的结点的next指向newNode
p.next = newNode;
//5.size加一
size++;
}
@Override
public void add(Object e) {
//为add(int i,Object e)的特殊情况
add(size, e);
}
@Override
public Object remove(int i) {
//判断索引是否越界
if (i < 0 || i >= this.size) {
throw new MyIndexOutOfBoundsException("非法索引:" + i);
}
Node p = this.head;
for (int j = 0; j < i; j++) {
p = p.next;
}
//for循环执行完成之后,p代表索引为i-1的元素
//用一个临时变量接收被删除的元素
Node temp = p.next;
p.next = temp.next;
temp.next = null;
size--;
return temp.data;
}
@Override
public boolean remove(Object e) {
Node p = this.head.next;
if (e != null) {
for (int i = 0; i < this.size; i++) {
if (p.data.equals(e)) {
this.remove(i);
return true;
}
p = p.next;
}
} else {
for (int i = 0; i < this.size; i++) {
if (p.data == null) {
this.remove(i);
return true;
}
p = p.next;
}
}
size--;
return false;
}
@Override
public Object replace(int i, Object e) {
//判断索引是否越界
if (i < 0 || i >= this.size) {
throw new MyIndexOutOfBoundsException("非法索引:" + i);
}
Node p = this.head;
for (int j = 0; j <= i; j++) {
p = p.next;
}
//for循环执行完成之后,p代表索引为i的元素
Object obj = p.data;
p.data = e;
return obj;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("[");
//第一个储存数据的结点是head的下一个结点
Node p = this.head.next;
for (int i = 0; i < this.size; i++) {
if (i != this.size - 1) {
sb.append(p.data + ",");
} else {
sb.append(p.data);
}
p = p.next;
}
sb.append("]");
return sb.toString();
}
}
编写测试类:
package com.qianyu.test;
import com.qianyu.dataStructure.lineTable.ArrayList;
import com.qianyu.dataStructure.lineTable.SingleLinkedList;
/**
* @author lijing
* @date 2019-03-21-20:01
* @discroption 测试SingpleLinedList
*/
public class TestSingpleLinedListA {
public static void main(String[] args) {
SingleLinkedList list = new SingleLinkedList();
list.add(1);
list.add(2);
list.add(3);
System.out.println(list);
list.add(1, "第二个元素");
System.out.println(list);
System.out.println(list.isEmpty());
System.out.println(list.contains(3));
System.out.println(list.contains(5));
System.out.println(list.indexOf(3));
System.out.println(list.indexOf(5));
System.out.println(list.remove(0));
System.out.println(list);
list.replace(1, "hello");
System.out.println(list);
list.replace(2, "world");
System.out.println(list);
System.out.println(list.get(0));
try {
list.get(3);
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果: