0. 链表 Linked List
class Node{
E e;
Node next;
}
优点: 真正的动态,不需要处理数组固定容量的问题 缺点: 丧失了随机访问能力,只能从依次顺序访问
1. 创建节点
/**
* Created by Enzo Cotter on 2018/7/12.
*/
public class LinkedList <E > {
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();
}
}
private Node head;
private int size;
public LinkedList (){
head = null ;
size = 0 ;
}
public int getSize (){
return size;
}
public boolean isEmpty (){
return size == 0 ;
}
}
2. 添加元素
public void addFirst (E e){
head = new Node(e,head);
size++;
}
public void add (int index,E e){
if (index <0 || index > size)
throw new IllegalArgumentException("Add failed, Illegal index." );
if (index == 0 )
addFirst(e);
else {
Node prev = head;
for (int i = 0 ; i < index -1 ; i ++)
prev = prev.next;
prev.next = new Node(e,prev.next);
size++;
}
}
public void addLast (E e){
add(size,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++;
}
public void addFirst (E e){
add(0 ,e);
}
public void addLast (E e){
add(size,e);
}
3. 查找和修改
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 );
}
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;
}
public boolean contains (E e){
Node cur = dummyhead.next;
while (cur != null ){
if (cur.e.equals(e))
return true ;
cur = cur.next;
}
return false ;
}
@Override
public String toString () {
StringBuilder res = new StringBuilder();
Node cur = dummyhead.next;
while (cur != null ){
res.append(cur + "->" );
cur = cur.next;
}
res.append("null" );
return res.toString();
}
4. 链表中删除元素
public E remove ( int index){
if (index <0 || index >= size)
throw new IllegalArgumentException("Remove failed, Illegal 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 );
}
5. 用链表实现一个栈
public interface Stack <E > {
void push(E);
E pop();
E peek();
int getSize();
boolean isEmpty();
}
public class LinkedListStack <E > implements Stack <E > {
private LinkedList<E> list;
public LinkedListStack (){
list = new LinkedList<>();
}
@Override
public int getSize () {
return list.getSize();
}
@Override
public boolean isEmpty () {
return list.isEmpty();
}
@Override
public void push (E e){
list.addFirst(e);
}
@Override
public E pop (){
return list.removeFirst();
}
@Override
public E peek (){
return list.getFirst();
}
@Override
public String toString () {
StringBuilder res = new StringBuilder();
res.append("Stack: top " );
res.append(list);
return res.toString();
}
}
6.用链表实现一个队列
由于链表的特殊性,需要借助个尾指针来指向最后一个节点,这样队列中添加元素时间复杂度O(N);
/**
* Created by Enzo Cotter on 2018/7/16.
*/
public class LinkedListQueue <E > implements Queue <E > {
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();
}
}
private Node head,tail;
private int size;
public LinkedListQueue (){
head = null ;
tail = null ;
size = 0 ;
}
@Override
public int getSize () {
return size;
}
@Override
public boolean isEmpty () {
return size == 0 ;
}
@Override
public void enqueue (E e) {
if (tail == null ){
tail = new Node(e);
head = tail;
}
else {
tail.next = new Node(e);
tail = tail.next;
}
size ++;
}
@Override
public E dequeue () {
if (isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty queue." );
Node retNode = head;
head = head.next;
retNode.next = null ;
if (head == null )
tail = null ;
size -- ;
return retNode.e;
}
@Override
public E getFront () {
if (isEmpty())
throw new IllegalArgumentException("Queue is empty" );
return head.e;
}
@Override
public String toString () {
StringBuilder res = new StringBuilder();
res.append("Queue: front " );
Node cur = head;
while (cur != null ){
res.append(cur + "->" );
cur = cur.next;
}
res.append("NULL tail" );
return res.toString();
}
}