实现链表
package com.lt.datastructure.LinkedList;
public class LinkedList<E> {
//虚拟头结点
private Node dummyhead;
private int size;
public 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();
}
}
public LinkedList(){
dummyhead = new Node(null,null);
size = 0;
}
// 返回元素个数
public int getSize(){
return size;
}
// 返回链表是否为空
public boolean isEmpty(){
return size == 0;
}
// 链表添加元素
public void add(int index,E e){
if(index<0 || index >size)
throw new IllegalArgumentException("Add failed");
//index的前一个位置
Node prev = dummyhead;//dymmyhead.next 则 for(; i<index-1;)
for(int i=0;i<index;i++){
prev = prev.next;
}
// Node node = new Node(e);
// node.next = prev.next;
// //前一个元素指向node
// prev.next = node;
prev.next = new Node(e,prev.next);
size++;
}
// 在链表头添加元素
public void addFirst(E e){
// Node node = new Node(e);
// //指向原来的第一个元素
// node.next = head;
// //head指向第一个元素
// head = node;
// head = new Node(e,head);
add(0, e);
}
// 链表末尾添加元素
public void addLast(E e){
add(size,e);
}
//获取链表的第index个元素
public E get(int index){
if(index<0||index>=size){
throw new IllegalArgumentException("Get failes.Illegal index");
}
//目的是从第一个开始
Node cur = dummyhead.next;
for(int i =0; i<index ; i++){
//遍历index次,从指向1到指向index
cur = cur.next;
}
return cur.e;
}
//获取第一个元素
public E getFirst(){
return get(0);
}
//获取最后一个元素
public E getLast(){
return get(size);
}
//修改链表的第index(0-size)个元素为e
public void set(int index , E e){
if(index<0 || index>size ){
throw new IllegalArgumentException("Set failed. Illeagal index");
}
//目的是找到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;
}
//在链表中删除指定位置的元素
//找到待删除结点的前一个结点,使其next指向delNode.next,而delNode.next指向Null
public E remove(int index){
if(index<0 || index>=size ){
throw new IllegalArgumentException("remove failed. Illeagal index");
}
//找到前一个结点,使其指向删除结点的后一个结点
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);
}
//toString
@Override
public String toString() {
StringBuilder res = new StringBuilder();
// Node cur = dummyhead.next;
// while(cur!=null){
// res.append(cur+"->");
// cur = cur.next;
// }
for(Node cur= dummyhead.next; cur!=null; cur=cur.next){
res.append(cur+"->");
}
res.append("null");
return res.toString();
}
}
测试:
package com.lt.datastructure.LinkedList;
public class Main {
public static void main(String[] args) {
LinkedList<Integer> linkedList = new LinkedList<>();
for(int i=0 ; i<5 ; i++){
linkedList.addFirst(i);
System.out.println(linkedList);
}
linkedList.add(2, 666);
System.out.println(linkedList);
linkedList.remove(2);
System.out.println(linkedList);
//
linkedList.removeFirst();
System.out.println(linkedList);
//
linkedList.removeLast();
System.out.println(linkedList);
}
}
测试结果:

复杂度分析:
- 增 :需要遍历找到找到前一个位置 O(n/2) O(n)
- 删 :需要遍历,平均为O(n/2) O(n)
- 改 : 需要遍历,平均为O(n/2) O(n)
- 查 :需要遍历,平均为O(n/2) O(n)
和数组对比:
- 数组有索引的时候,可以快速访问
- 如果只对链表头进行操作,和数组的时间复杂度差不多:O(1)
- 链表是动态的,不会浪费内存空间