这是这段时间学习链表的笔记和总结。
链表是一种线性数据结构,实现真正的动态数据结构,链表是一种比较简单的动态数据结构。
链表Linked List
LinkedList的数据以节点为单位,其中一个节点应该包括当前存储的内容以及下一节点的引用,如果不存在下一节点,则下一节点引用为空。
链表的优点是真正实现动态存储,不需要处理固定容量的问题,需要添加节点直接new一个新的节点,再把它添加到链表中。确定是随机访问能力弱,访问某一节点必须通过遍历的方式去实现。
链表和数组的比较:
数组是一块连续的内存空间,支持索引快速查询。
而链表真正实现动态数据结构,不需要手动维护类似于数组固定容量的问题。
链表的实现:
实现节点数据结构,包含数据存储和下一节点引用
private class Node{
public E e;
public Node next;
public Node(E e, Node next){
this.e = e;
this.next = next;
}
public Node(E e){
this(e, null);
}
public Node(){
this(null, null);
}
@Override
public String toString(){
return e.toString();
}
}
LinkedList构造方法的实现
private Node dummyHead;
private int size;
public LinkedList(){
dummyHead = new Node();
size = 0;
}
dummyHead表示的是一个虚拟头结点,并不作为链表存储真实数据的真正成员,它的存在只是让我们的链表为空时头结点任然存在,可以简化我们编写代码。
添加操作,包括往第一个位置和最后一个位置添加
// 在链表的index(0-based)位置添加新的元素e
public void add(int index, E e){
if(index < 0 || index > size)
throw new IllegalArgumentException("Add failed. Illegal index.");
Node prev = dummyHead;
for(int i = 0 ; i < index ; i ++)
prev = prev.next;
prev.next = new Node(e, prev.next);
size ++;
}
// 在链表头添加新的元素e
public void addFirst(E e){
add(0, e);
}
// 在链表末尾添加新的元素e
public void addLast(E e){
add(size, e);
}
查找操作
// 获得链表的第index(0-based)个位置的元素
public E get(int index){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Get failed. Illegal index.");
Node cur = dummyHead.next;
for(int i = 0 ; i < index ; i ++)
cur = cur.next;
return cur.e;
}
// 获得链表的第一个元素
public E getFirst(){
return get(0);
}
// 获得链表的最后一个元素
public E getLast(){
return get(size - 1);
}
修改操作
// 修改链表的第index(0-based)个位置的元素为e
public void set(int index, E e){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Set failed. Illegal index.");
Node cur = dummyHead.next;
for(int i = 0 ; i < index ; i ++)
cur = cur.next;
cur.e = e;
}
查找链表是否存在某个元素
// 查找链表中是否有元素e
public boolean contains(E e){
Node cur = dummyHead.next;
while(cur != null){
if(cur.e.equals(e))
return true;
cur = cur.next;
}
return false;
}
删除操作
// 从链表中删除index(0-based)位置的元素, 返回删除的元素
public E remove(int index){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Remove failed. Index is illegal.");
Node prev = dummyHead;
for(int i = 0 ; i < index ; i ++)
prev = prev.next;
Node retNode = prev.next;
prev.next = retNode.next;
retNode.next = null;
size --;
return retNode.e;
}
// 从链表中删除第一个元素, 返回删除的元素
public E removeFirst(){
return remove(0);
}
// 从链表中删除最后一个元素, 返回删除的元素
public E removeLast(){
return remove(size - 1);
}
// 从链表中删除元素e
public void removeElement(E e){
Node prev = dummyHead;
while(prev.next != null){
if(prev.next.e.equals(e))
break;
prev = prev.next;
}
if(prev.next != null){
Node delNode = prev.next;
prev.next = delNode.next;
delNode.next = null;
size --;
}
}
以上就是一个LinkedLsit的实现,这里作为笔记记录下。