带头单链表就是在链表头部放一个空的链表,这样每次在操作链表时,不需要考虑链表是否存在节点,简化操作。
@SuppressWarnings("unchecked")
public class List<T> {
//内部节点类
private class Node<T>{
private Object val;
private Node next;
private Node(T t,Node next){
this.val = t;
this.next = next;
}
public T getVal() {
return (T)val;
}
public void setVal(T t) {
this.val = t;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return ""+val;
}
}
private Node head;//头结点
private Node rear;//尾结点
private int length;//实际元素个数
//初始化链表
public List(){
head = new Node(null,null);
rear = head;
length = 0;
}
//删除指定位置的元素
public void remove(int index){
if(index < 1 || index > length){
throw new RuntimeException("超出链表节点范围!");
}
if(index == 1){ //头部删除
Node target = head.next;
Node node = target.next;
head.next = node;
target = null;
}else if(index == length){ //尾部删除
Node node = getNode(length-1);
node.setNext(null);
rear = node;
}else{ //中间删除
Node prev = getNode(index-2);
Node target = prev.getNext();
Node node = target.getNext();
prev.setNext(node);
target = null;
}
length--;
}
// 尾部添加元素,因为表头有个空节点,
// 所以有没有实际元素都是一样的操作
// 不需要额外判断是否为空
public void add(T t){
rear.next = new Node(t,null);
rear = rear.next;
length++;
}
//获取指定位置上的元素
public T get(int index){
return (T)getNode(index).getVal();
}
//指定位置插入
//如果index == 0,是插入表头
public void insert(int index,T t){
if(index < 0 || index > length){
throw new RuntimeException("超出链表节点范围!");
}
Node node = new Node(t,null);
if(index == 0){ //头部插入
Node temp = head.next;
head.next = node;
node.next = temp;
length++;
}else if(index == length){ //尾部插入
add(t);
}else { //中间插入
Node temp = getNode(index);
Node follow = temp.getNext();
temp.next = node;
node.next = follow;
length++;
}
}
//获取指定位置的节点
private Node getNode(int index){
//TODO:是否先判断length == 0
if(index < 1 || index > length){
throw new RuntimeException("超出链表节点范围!");
}
if(index == length){ //获取尾结点,不需要遍历
return rear;
}
Node node = head.getNext();
for(int i = 1; i <= index ; i++){
node = node.next;
}
return node;
}
//求长度
public int length(){
return length;
}
@Override
public String toString() {
Node current = head.getNext();
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int n = 1;n<=length;n++){ //打印元素
sb.append(current+",");
current = current.getNext();
}
sb.deleteCharAt(sb.length()-1); //删除最后多余的一个逗号
sb.append("]");
if(sb.length()<2){ //字符串小于2,说明没有元素,打印" [] ";
return "[]";
}
return sb.toString();
}
}