基本介绍
实现方法:
1. 简单数组
2. 简单链表
数组
对于表的所有操作都可通过简单数组来实现,虽然数组是固定容量的,但在需要时我们可通过创建一个新数组来扩大容量。使用数组实现其遍历输出时间是线性的,查找花费常数时间。但插入和删除将花费大量开销,当然要看插入删除所发生的位置。最坏情况为在位置0操作,最好情况则为在末尾操作。
链表
与数组相比链表的输出和查找时间都将增大,然而当我们频繁的插入删除时链表将为我们节约大量时间。它每一个节点(Node)都包含两方面的内容:
1.节点本身的数据(data);
2.下一个节点的信息(next)。 (如果为双链表则还将包含上一个节点信息(prev))
java中的实现
在java.util包中集合框架Collection接口的继承接口List主要用于实现表。
Vector:
基于数组(Array)的List,封装了数组所不具备的一些功能进而方便我们使用,Vector是线程同步的(sychronized)的,这也是Vector和ArrayList 的一个的重要区别。
ArrayList:
同Vector一样是一个基于数组上的链表,但是不同的是ArrayList不是同步的。因此在性能上要比Vector好,但是需要自己在管理线程的同步问题。
LinkedList:
链表LinkedList不同于前面两种List,它不是基于数组的,所以不受数组性能的限制。
今后使用中我们可直接通过实例化对象来实现表结构,如:List list = new ArrayList();
当然我们也可尝试编写属于自己的ArrayList与LinkedList在编写中将用到迭代器,内部类,和嵌套类。
代码实现:
MyArrayList:
import java.util.Iterator;
public class MyArrayList<AnyType> implements Iterable<AnyType>{
private static final int addsize=10 ;
private int nowsize ;
private AnyType[] theArray ;
public MyArrayList()
{
this.clear();
}
public void clear()
{
this.nowsize = 0 ;
arraychange(addsize);
}
public void arraychange(int newsize)
{
if(newsize>nowsize)
return;
else
{
AnyType []old = theArray ;
theArray = (AnyType []) new Object[newsize] ;
for(int i=0;i < size();i++)
theArray[i] = old[i] ;
}
}
public int size()
{
return nowsize;
}
public AnyType set(int index , AnyType news){
if(index>=this.size() || index<0)
throw new ArrayIndexOutOfBoundsException();
AnyType old = this.theArray[index];
this.theArray[index] = news ;
return old ;
}
public AnyType get(int index ){
if(index>=this.size() || index<0)
throw new ArrayIndexOutOfBoundsException();
AnyType old = this.theArray[index];
return old ;
}
public void add(AnyType news){
this.add(this.size(), news);
}
public void add(int index , AnyType news){
if(this.theArray.length==this.size())
this.arraychange(this.size()*2+1);
if(index>=this.size() || index<0)
throw new ArrayIndexOutOfBoundsException();
for(int i=this.nowsize;i<index;i--)
this.theArray[i]=this.theArray[i-1] ;
this.theArray[index] = news ;
this.nowsize++;
}
public void remove(int index ){
if(index>=this.size() || index<0)
throw new ArrayIndexOutOfBoundsException();
for(int i = index ; i < this.nowsize -1 ; i++)
this.theArray[i] = this.theArray[i+1] ;
this.nowsize--;
}
@Override
public Iterator<AnyType> iterator() {
return new ArrayListIterator<AnyType>();
}
private class ArrayListIterator<AnyType> implements Iterator<AnyType>
{
private int c = 0;
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return c<size();
}
@Override
public AnyType next() {
if(!hasNext())
throw new ArrayIndexOutOfBoundsException();
return (AnyType) theArray[c++];
}
@Override
public void remove() {
MyArrayList.this.remove(c--);
}
}
}
MyLinkedList:此方法中迭代器与上一方法大致相同,所以未做实现
public class MyLinkedList<T> implements Iterable<T> {
private int size ;
private int count = 0 ;
private Node<T> begin ;
private Node<T> end ;
public MyLinkedList ()
{
this.clear() ;
}
public void clear() {
this.begin = new Node<T>(null,null,null);
this.end = new Node<T>(null,this.begin,null);
this.begin.next = this.end ;
}
public int size() {
return this.size;
}
public boolean isEmpty()
{
return size() == 0 ;
}
public boolean add(T x)
{
this.add(this.size(),x);
return true;
}
public void add(int idx, T x) {
this.addBefore(this.getNode(idx),x);
}
public T get(int idx, T x) {
return getNode(idx).data;
}
public T set(int idx, T x) {
Node<T> old = getNode(idx) ;
T o = old.data ;
old.data = x ;
return o ;
}
public T remove(int idx) {
return remove(getNode(idx));
}
private T remove(Node<T> n) {
n.next.prev = n.prev ;
n.prev.next = n.next;
this.size--;
this.count++;
return n.data;
}
private void addBefore(Node<T> node, T x) {
Node<T> n = new Node<T> (x,node.prev,node.next);
n.prev.next = n ;
node.prev = n;
this.size++;
this.count++;
}
private Node<T> getNode(int idx) {
Node<T> p;
if(idx<0||idx>this.size())
throw new ArrayIndexOutOfBoundsException();
if(idx<this.size()/2)
{
p = this.begin;
for(int i=0;i<idx;i++)
p=p.next;
}
else
{
p = this.end;
for(int i=this.size();i>idx;i--)
p=p.prev;
}
return p;
}
@Override
public Iterator<T> iterator() {
return null;
}
public static class Node<T>{
private T data;
private Node<T> prev ;
private Node<T> next ;
public Node(T d , Node<T> p,Node<T> n )
{
this.data = d ;
this.prev = p ;
this.next = n ;
}
}