为了将存储表元素的所有单元用指针串联起来,我们让每个单元包含一个元素域和一个指针域,其中的指针指向表中下一个元素所在的单元。例如,如果表是a1,a2,…,an ,那么含有元素ai的那个单元中的指针应指向含有元素ai+1的单元(i=1,2,…,n-1)。含有an的那个单元中的指针是空指针null。此外,通常我们还为每一个表设置一个表头单元head,其中的指针指向开始元素中所在的单元,但表头单元head中不含任何元素。设置表头单元的目的是为了使表运算中的一些边界条件更容易处理。这一点我们在后面可以看到。如果我们愿意单独地处理诸如在表的第一个位置上进行插人与删除操作等边界情况,也可以简单地用一个指向表的第一个单元的指针来代替表头单元。
上述这种用指针来表示表的结构通常称为单链接表,或简称为单链表或链表。单链表的逻辑结构如图2.1所示。表示空表的单链表只有一个单元,即表头单元head,其中的指针是空指针null。
本人自己实现的单链表类 可以媲美 linklist
package com.data.tree;
//单向链表
public class SimpleLinkList<E> {
// 定义单链表头用于标示第一个元素
private transient ELinkList<E> head = new ELinkList<E>(null, null);
// 定义单链表长度
public transient int size = 0;
// 添加第一个元素
public void addFirst(E ele) {
// 实例化链表元素
ELinkList<E> temp = new ELinkList<E>(ele, null);
// 如果没有第一个元素 添加第一个元素为temp
if (head.next == null) {
head.next = temp;
// 存在第一个元素 当前元素的指向以前的一个元素 同时head指向当前元素
} else {
temp.next = head.next;
head.next = temp;
}
size++;
}
// 添加第一个元素
public void addLast(E ele) {
// 实例化链表元素
ELinkList<E> temp = new ELinkList<E>(ele, null);
// 获取最后一个元素 并且最后一个元素指向当前元素
ELinkList<E> e = getLastLink(null);
if (e == null)
addFirst(ele);
else {
e.next = temp;
size++;
}
}
// 添加元素也是往第一个位置添加元素
public void add(E ele) {
addLast(ele);
}
// 删除第一个元素 判断第一个元素是否存在 如果存在 head指向第一个元素的下一个元素
public void removeFirst() throws Exception {
if (head.next != null) {
head.next = head.next.next;
size--;
} else {
throw new Exception("没有第一个元素");
}
}
// 删除某个元素 因为没有指针指向第一个元素 所以添加参数 前参 和当前参数
public boolean remove(E e, ELinkList<E> previous, ELinkList<E> current) {
// 如果前面不是是空 后面一个是空 说明到达最后 直接返回false
if (previous != null && current == null) {
return false;
}
// 定义临时参数
ELinkList<E> currentlnk = null;
ELinkList<E> previouslnk = null;
// 如果当前参数为null 当前参数就是 第一个元素 也就是head.next
// 前一个参数就是head
if (current == null && previous == null) {
currentlnk = head.next;
previouslnk = head;
// 如果有值则 使用当前值
} else {
currentlnk = current;
previouslnk = previous;
}
// 判断传递的值是否等于 当前节点的值 相等则 前面的节点指向相等节点的后一个节点
if (e.equals(currentlnk.data)) {
previouslnk.next = currentlnk.next;
size--;
return true;
// 如果找不到 递归查找 知道找到为止
} else {
return remove(e, currentlnk, currentlnk.next);
}
}
// 重第一个元素开始遍历找到并删除该元素
public boolean remove(E e) {
return remove(e, null, null);
}
// 是否为空
public boolean isEmpty() {
if (head.next != null)
return false;
return true;
}
// 获得首个元素
public E getFirst() {
if (head.next == null)
return null;
return head.next.data;
}
//获取指定索引的值 一直next .next 就会根据次数去next 去的值
public E get(int index) throws Exception {
if (index + 1 > size) {
throw new IndexOutOfBoundsException("索引越界");
}
ELinkList<E> tmplnk = head;
for (int i = 0; i <= index; i++) {
tmplnk = tmplnk.next;
}
return tmplnk.data;
}
//为了实现递归查询带的参数
public E getLast(ELinkList<E> link) {
ELinkList<E> next = null;
if (link == null)
next = head.next;
else
next = link;
if (next.next == null)
return next.data;
else
return getLast(next.next);
}
private ELinkList<E> getLastLink(ELinkList<E> link) {
ELinkList<E> next = null;
if (link == null)
next = head.next;
else
next = link;
if (next == null)
return null;
if (next.next == null)
return next;
else
return getLastLink(next.next);
}
// 获得最后一个元素
public E getLast() {
return getLast(null);
}
private class ELinkList<E> {
public E data;
public ELinkList<E> next;
public ELinkList(E data, ELinkList<E> next) {
this.data = data;
this.next = next;
}
public ELinkList(E data) {
this(data, null);
}
}
}
转载请注明出处
地址 http://blog.csdn.net/liaomin416100569/archive/2010/04/27/5532927.aspx
作者 廖敏