链表与数组
链表是最简单的动态数据结构,相比与数组优缺点:
- 优点:链表实现了真正的动态,不需要处理固定容量带来的扩容缩容等情况;
- 缺点:链表不能根据索引直接访问数据
话不多说,上代码
/*
* 实现第一个动态数据结构链表
* */
public class LinkedList<E> {
/*
* 将Node作为私有的内部类
* */
private class Node<E>{
private E e;
private 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();
}
}
// 定义链表头
private Node head;
// 定义一个size存储链表实际元素个数
private int size;
// 为了add操作一致性,设置一个虚拟节点
private Node dummyHead;
/*
* 构造方法 不同于数组,链表不需要指定容量
* */
public LinkedList(){
head=null;
size=0;
dummyHead=new Node(null,null);
}
public int getSize() {
return size;
}
// 在链表头添加元素
// public void addFirst(E e){
Node node=new Node(e);
node.next=this.head;
head=node;
// head=new Node(e,head);
// size++;
// }
/*
* 在链表中间添加元素
* */
public void add(int index,E e){
if(index<0||index>size){
throw new IllegalArgumentException("添加失败,索引不合法");
}
// if(index==0){
// addFirst(e);
// }else {
// ...
// }
Node prev=dummyHead;
for (int i = 0; i < index; i++) {
prev=prev.next;
}
prev.next=new Node(e,prev.next);
size++;
}
public void addFirst(E e){
add(0,e);
}
public void addLast(E e){
add(size,e);
}
/*
* 链表元素的删除
* */
public E remove(int index){
Node prev=dummyHead;
for (int i = 0; i < index; i++) {
prev=prev.next;
}
Node delNode=prev.next;
prev.next=delNode.next;
//便于回收这个被删除的元素
delNode.next=null;
size--;
return (E) delNode.e ;
}
public E removeFirst(){
return remove(0);
}
public E removeLast(){
return remove(size-1);
}
/*
* 获取链表的第index(0-based)个位置
* 在链表中不是一个常用的操作,只作练习使用
* */
public E get(int index){
if(index<0||index>size){
throw new IllegalArgumentException("获取失败,索引不合法");
}
// 从第一个节点开始
Node cur=dummyHead.next;
for (int i = 0; i < index; i++) {
cur=cur.next;
}
// 这里要强制类型转换,没看懂?
return(E) cur.e;
}
/*
* 获得链表的第一个元素
* */
public E getFirst(){
return get(0);
}
/*
* 获得链表的最后元素
* */
public E getLast(){
return get(size);
}
/*
* 查找链表中是否有元素e
* */
public boolean contains(E e){
Node cur=dummyHead.next;
while(cur!=null){
if(e.equals(cur.e)){
return true;
}
cur=cur.next;
}
return false;
}
/*
* 链表非空判断
* */
public boolean isEmpty(){
return size==0;
}
/*
* 修改链表的第index(0-based)个位置元素
* 在链表中不是一个常用的操作,只作练习使用
* */
public void set(int index,E e){
if(index<0||index>size){
throw new IllegalArgumentException("更新失败,索引不合法");
}
Node cur=dummyHead.next;
for (int i = 0; i < index; i++) {
cur=cur.next;
}
cur.e=e;
}
@Override
public String toString(){
StringBuilder buffer=new StringBuilder();
Node cur=dummyHead.next;
while(cur!=null){
buffer.append(cur+"->");
cur=cur.next;
}
buffer.append("NULL");
return buffer.toString();
}
/*
* 测试一下写的链表
* */
public static void main(String[] args) {
LinkedList<Integer> list=new LinkedList<>();
for (int i = 0; i < 10; i++) {
list.addLast(i);
}
System.out.println(list);
list.set(5,666);
System.out.println(list);
list.remove(5);
System.out.println(list);
}
}