For a detailed explanation of the data structure linked list, please move
The ordinary doubly linked list implemented by Java can refer to
With the introduction of generics, the problem of parameters during downcasting of the Object class can be solved, and the ClassCastException exception during downcasting can be avoided.
Look code
package test;
/*
* 基于泛型工厂模式实现的双链表
* */
interface Link<T> {
// 链表初始化
void init();
// 链表尾插一个节点
void add(T t);
// 删除下表为 index 的节点
boolean remove(int index);
// 判断链表中是否包含给定值的节点
boolean contain(T t);
// 给定值在链表中的下标
int indexOf(T t);
// 设置给定下标的结点的值
boolean set(int index, T t);
// 得到指定下标的结点的值
T get(int index);
// 返回链表长度
int length();
// 清空链表
void clean();
// 已数组的形式返回整个链表的值
T[] toArray();
// 打印链表
void printLink();
}
class LinkImpl<T> implements Link<T> {
private Node first;
private Node last;
private Integer size;
// 存储节点信息
private class Node {
public Node(T data) {
this.data = data;
}
Node next ;
Node prev ;
T data;
}
@Override
public void init() {
// TODO Auto-generated method stub
this.last = this.first = null;
this.size = 0;
}
@Override
public void add(T t) {
// TODO Auto-generated method stub
// 创建接节点
Node newnode = new Node(t);
// 当前链表为空
if(this.size == 0) {
this.first = newnode;
this.last = newnode;
newnode.next = null;
newnode.prev = null;
this.size++;
} else {// 节点非空
// 拷贝当前尾节点指向
Node tmp = this.last;
// 尾插
tmp.next = newnode;
newnode.prev = tmp;
// 改变尾节点指向
this.last = newnode;
newnode.next = null;
this.size++;
}
}
@Override
public boolean remove(int index) {
// TODO Auto-generated method stub
// 链表为空
if(this.size == 0) {
return false;
} else if(index>=this.size || index<0) {// index非法输入
return false;
} else if(this.last == this.first) {// 链表只有一个节点
this.first = this.last = null;
this.size = 0;
} else if(index == 0) {// 删除头节点
this.first = this.first.next;
this.size--;
} else if(index == this.size-1) {// 删除尾节点
this.last = this.last.prev;
this.size--;
} else {// 普通情况
// 便利寻找第 index 个节点
Node cur = this.first;
for( int i = 0; i <= index; i++) {
cur = cur.next;
}
cur.prev.next = cur.next;
cur.next.prev = cur.prev;
this.size--;
}
return true;
}
@Override
public boolean contain(T t) {
// TODO Auto-generated method stub
// 遍历链表
Node cur = this.first;
for( int i = 0; i < this.size; i++) {
if(cur.data == t) {
return true;
}
cur = cur.next;
}
return false;
}
@Override
public int indexOf(T t) {
// TODO Auto-generated method stub
// 遍历链表
Node cur = this.first;
int i = 0;
for( ; i < this.size; i++) {
if(cur.data == t) {
return i;
}
cur = cur.next;
}
return -1;
}
@Override
public boolean set(int index, T t) {
// TODO Auto-generated method stub
// index 非法输入
if(index >= this.size) {
return false;
}
// 遍历数组
Node cur = this.first;
for(int i = 0; i <= index; i++) {
cur = cur.next;
}
cur.data = t;
return true;
}
@Override
public T get(int index) {
// TODO Auto-generated method stub
// index 非法输入
if(index >= this.size) {
System.out.println("index 非法输入");
}
// 遍历数组
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() {
// TODO Auto-generated method stub
this.first = this.last = null;
this.size = 0;
}
@Override
public T[] toArray() {
// TODO Auto-generated method stub
Object[] arr = new Object[this.size];
@SuppressWarnings("unchecked")
T[] data = (T[])arr;
Node cur = this.first;
for(int i = 0; i < this.size; i++) {
data[i] = cur.data;
cur = cur.next;
}
return data;
}
@Override
public void printLink() {
// TODO Auto-generated method stub
Node cur = this.first;
for(int i = 0; i < this.size; i++) {
System.out.println(cur.data);
cur = cur.next;
}
}
}
// 一个泛型工厂类
class Factory<T> {
private Factory() {}
public static <T> LinkImpl<T> getInstance() {
return new LinkImpl<T>();
}
}
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
LinkImpl<String> link = Factory.getInstance();
link.init();
// 测试
}
}