java数据结构:表、栈、队列

本博客讨论最简单最基本的三种数据结构,几乎所有程序都要显式的使用至少一种数据结构,本文重点为:抽象数据类型的概念、如何有效执行表的操作、栈和队列ADT及其应用、ArrayList和LinkedList的实现代码。

ADT概念

抽象数据类型(abstract data type 、ADT):
带有一组操作的一些对象的集合,可以有添加、删除、包含、查找等操作;
表ADT
形如 A0A1A2A3An 的表,我们称其大小为n。表的实现形式有数组实现、链表实现等。

in java Collection API

Collection接口

collection接口抽象出了集合的概念,即存储一组类型相同的对象。该接口的主要方法定义如下:

public interface Collection<AnyType> extends Iterable<AnyType>{
    int size();
    boolean isEmpty();
    void clear();
    boolean contains(AnyType x);
    boolean add();
    boolean reamove();
    java.util.Iterator<AnyType> iterator();
}

方法名称都可以顾名思义,在此不做赘述。

Iterator接口

实现Iterable接口的集合必须提供一个称为iterator的方法,该方法返回一个Iterator类型的对象。Iterator为java.util中定义的一个接口:

//Iterator接口
public interface Iterator<AnyType>{
    boolean hashNext();
    AnyType next();
    void remove();
}

//增强型for循环调用的print例程(利用Iterator进行遍历)
public static <AnyType> void print(Collection<AnyType> coll){
    Iterator<AnyType> itr = coll.iterator;
    while(itr.hashNext()){
        AnyType item = itr.next();
        System.out.println(item);
    }
}

值得一提的是Iterator中的remove方法和Collection中的remove方法:如果对正在被迭代的集合进行结构上的改变(add、remove、clear)那么迭代器将不再合法(ConcurrentModificationException),而此时迭代器调用它自己的remove方法就仍然是合法的;

List接口、ArrayList类和LinkedList类

List接口由Java.util包中的List接口指定,List接口继承了Collection接口(包含了其所有方法)。List接口中比较重要的方法如下:

public interface List<AnyType> extends Collection<AnyType>{
    AnyType get(int idx);
    AnyType set(int idx,AnyType newVal);
    void add(int idx,AnyType x);
    void remove(int idx);

    ListIterator<AnyType> listIterator(int pos);
}

List ADT 有两种流行的实现形式:ArrayList对于get和set的调用花费常数时间,但插入和删除代价昂贵;LinkedList插入删除都是常数时间的操作,但get方法代价昂贵;

ListIterator接口

ListIterator接口扩展了List的Iterator功能:

public interface ListIterator<AnyType> extends Iterator<AnyType>{
    //完成list的反向遍历
    boolean hasPrevious();
    AnyType previous();
    //遍历中执行的add、set方法
    void add(AnyType x);
    void set(AnyType newVal);
}

ArrayList类的实现

本节给出ArrayList泛型类的实现,为避免冲突我们的类叫做MyArrayList。其中细节点有:

  1. MyArrayList将保持基础数组,数组容量,以及存储在MyArrayList中的当前项数。
  2. MyArrayList提供一种机制来改变基础数组的容量。通过获得一个新数组并将老数组拷贝到其中,允许虚拟机回收老数组。
  3. MyArrayList提供get、set实现
  4. MyArrayList提供基本的方法实现(size、isEmpty、clear、add、remove)。
  5. MyArrayList提供一个实现Iterator接口的类

基本类实现:

public class MyArrayList<AnyType> implements Iterator<AnyType>{
    private static final int DEFAULT_CAPACITY = 10;//初始容量
    private int theSize;//现容量
    private AnyType[] theItems;//存数据的数组

    public MyArryList(){//构造方法
        doClear();
    }
    public void clear(){//清除方法
        doClear();
    }
    private void doClear(){//list置空,大小回复默认
        theSize = 0;
        ensureCapacity(DEFAULT_CAPACITY);   
    }
    public int size(){//返回当前list大小
        return theSize;
    }
    public boolean isEmpty(){//判断size是否空
        return size() == 0;
    }
    public void trimToSize(){//除去数组多余的容量以节省空间
        ensureCapacity( size() );
    }
    public AnyType get( int idx ){//获得指定位置的数据
        if( idx < 0 || idx >= size() )
            throw new ArrayOutOfBondsException();
        return theItems[ idx ];
    }
    public AnyType set(int idx,AnyType newVal){//设置指定位置数据
        if(idx < 0 || idx >= size())
            throw new ArrayIndexOutOfBoundsException();
        AnyType old = theItems[ idx ];
        theItems[ idx ] = newVal;
        return old;
    }
    public void ensureCapacity(int newCapacity){//用容量更大的数组代替原有数组
        if( newCapacity < theSize )
            return;
        AnyType[] old = theItems;
        theItems = (AnyType []) new Object[ newCapacity ];
        for(int i = 0;i < size();i++)
            theItems[i] = old[i];
    }
    public boolean add(AnyType){//add方法一
        add( size(),x);
        return true;
    }
    public void add(int idx,AnyType x){//add方法二,扩容
        if(theItems.length == size());
            ensureCapacity(size()*2+1);
        for(int i = theSize;i>ids;i--){
            theItems[i] = theItems[i-1];
        }
        theItems[idx] = x
        theSize++;
    }
    public AnyType remove(int idx){//删除方法,平移
        AnyType removedItem = theItems[idx];
        for(int i = idx;i<size()-1;i++)
            theItems[i] = theItems[i+1];
        theSize--;
        return removedItem;
    }
    public java.util.Iterator<AnyType> iterator(){//遍历
        return new ArrayListIterator;
    }
    private class ArrayListIterator implements java.util.Iterator<AnyType>{//内部类
        private int current = 0;
        public boolean hasNext(){
            return current<size();
        }
        public AnyType next(){
            if(!hasNext)
                throw new java.util.NoSuchElementException;
            return theItems[current++];
        }
        public void remove(){
            MyArrayList.this.remove(--current);
        }
    }
}

代码展示了两个版本的add方法,第一个是添加到表的末端,并且通过调用添加到指定位置的版本得以实现。这个版本代价非常昂贵,它需要指定位置及其后面的元素后移,而且会涉及到扩容。
有关iterator(表遍历)的方法实现可以参考我的另一篇博文:设计模式之Iterator。
未完待续…

LinkedList类的实现

博主正在完善中,敬请期待…

栈ADT

博主正在完善中,敬请期待…

队列ADT

博主正在完善中,敬请期待…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值