关于链表的详细讲解移步
Java比起C来说,在某些方面拥有着无与伦比的优势,接口类,覆写,工厂类的设计思想等,都可以是我们从繁重的代码任务中解放出来,话不多说,上代码
package Test;
// 定义一个接口类,类中进行方法的定义
interface Link {
void add(Object obj);
boolean remove(int index);
boolean contain(Object obj);
int indexOf(Object obj);
boolean set(int index, Object obj);
Object get(int index);
int length();
void clean();
Object[] toArray();
void printLink();
}
// 对接口中的方法进行覆写
class LinkImpl implements Link {
private Node first;
private Node last;
private int size = 0;
// 由于节点中的内容对其他类无关紧要,所以将它定义为private内部类,对外部不可见,只有覆写类可以看到
private class Node {
public Node(Object data) {
this.data = data;
}
Node next;
Node prev;
Object data;
}
@Override
// 链表添加元素使用尾插
public void add(Object obj) {
// 空链表时
if(this.size == 0) {
Node newnode = new Node(obj);
this.last = this.first = newnode;
this.size++;
}else {
Node newnode = new Node(obj);
Node tmp = this.last;
this.last = newnode;
tmp.next = newnode;
newnode.prev = tmp;
newnode.next = null;
this.size++;
}
}
@Override
// 删除链表中任意节点
public boolean remove(int index) {
if(index >= this.size || index < 0) {// 下标越界
return false;
}else if(this.size == 0) {// 空链表
return true;
}else if(this.last == this.first) {// 链表中只有一个元素
this.first = this.last = null;
this.size--;
}else if(index == 0) {// 删除头节点
Node tmp = this.first;
this.first = this.first.next;
tmp = null;
this.size--;
}else if(index == this.size-1) {// 删除尾节点
Node tmp = this.last;
this.last = this.last.prev;
tmp = null;
this.size--;
}else {// 普通情况
Node cur = this.first;
for(int i = 0; i <index; i++) {
cur = cur.next;
}
cur.next.prev = cur.prev;
cur.prev.next = cur.next;
this.size--;
}
return true;
}
@Override
// 判断数据是否包含在链表中
public boolean contain(Object obj) {
int i = 0;
Node cur = first;
for( ; i < size; i++) {
if(cur.data == obj) {
return true;
}
}
return false;
}
@Override
// 该数据是链表中的第几个,成功返回下标,查找失败返回-1
public int indexOf(Object obj) {
int i = 0;
Node cur = this.first;
for( ; i < size; i++) {
if(cur.data == obj) {
return i;
}
cur = cur.next;
}
return -1;
}
@Override
// 设置下标index的节点数据为obj
public boolean set(int index, Object obj) {
// index非法输入
if(index >= this.size) {
return false;
}
Node cur = this.first;
for(int i = 0; i < index; i++) {
cur = cur.next;
}
cur.data = obj;
return true;
}
@Override
// 得到链表中下标为index的节点数据
public Object get(int index) {
// index非法输入
if(index >= this.size) {
return false;
}
Node cur = this.first;
for(int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.data;
}
@Override
// 返回链表长度
public int length() {
// TODO Auto-generated method stub
return this.size;
}
@Override
// 清空整个链表
public void clean() {
// 空链表
this.first = this.last = null;
this.size = 0;
}
@Override
// 返回数组形式的链表数据
public Object[] toArray() {
Object[] data = new Object[this.size];
Node tmp = this.first;
for(int i = 0; i < this.size; i++) {
data[i] = tmp.data;
tmp = tmp.next;
}
return data;
}
@Override
// 打印整个链表
public void printLink() {
// TODO Auto-generated method stub
for(Object data:this.toArray()) {
System.out.println(data);
}
}
}
// 使用工厂设计模式,避免主函数中繁重的函数创建等行为
class Factory {
private Factory() {}
public static Link getLinkInstance() {
return new LinkImpl();
}
}
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Link link = Factory.getLinkInstance();
/*
Link接口中个方法的测试,由于篇幅,就不在这里赘述了
*/
link.printLink();
}
}