1. 程式人生 > >資料結構與演算法分析-順序表 SequenceList

資料結構與演算法分析-順序表 SequenceList

一.基本思路

       由於Java和C語言對陣列的限制,陣列在宣告時就要確定長度,雖然C語言可以動態控制記憶體分配,但也需要人為操作,且不會有是否越界的驗證。順序表的功能為可以隨時在陣列內插入、刪除,而不用擔心陣列越界。具體思路為在建立新的順序表時人為設定順序表的長度,當陣列資料存滿後,新建一個長度為原來兩倍的新陣列,將原資料放入新陣列中,並返回新陣列。

   操作                                具體實現思路以及時間複雜度
  新增  在資料最後端新增新元素。O(1)
  刪除  把要刪除節點後的節點向前移動1個節點。O(n)
  插入  把要插入位置上以及之後的向後移動1個節點。O(1)
  查詢  取決於查詢演算法。順序遍歷複雜度為O(n)

二. Java實現

   迭代器程式碼:

public interface Iterator<Type>{
    boolean hasNext();
    Type next();
    void remove();
}

   陣列程式碼:  

public class SequenceList<Type>{
    private final int DEFAULT_SIZE = 10; 
    Type[] elements;                     
    int size;
 
    //構造方法 無參
    public SequenceList(){
        elements = (Type[])new Object[DEFAULT_SIZE]; //實行強轉
        size = 0;
    }
    //構造方法 有參
    public SequenceList(int size) throws IllegalArgumentException{
        if(size<=0)
            throw new IllegalArgumentException("引數無效:陣列長度必須為正整數");
        else{
            elements = (Type[])new Object[size];
            this.size = 0;
        }
    }
    //返回索引上的元素
    public Type get(int index) throws IndexOutOfBoundsException,IllegalArgumentException{
        if(index<0||index>=elements.length)
            throw new IllegalArgumentException("引數無效:陣列索引必須為正整數且小於陣列長度");
        else if(index>=size)
            throw new IndexOutOfBoundsException("索引越界:索引應小於等於陣列長度");
        else
            return elements[index];
    }
    //查詢 這裡只實現最簡單的遍歷查詢 查詢成功返回索引 未找到返回-1
    public int find(Type data){
        index = 0;
        for(Type element:elements){
            if(element==data)
                return index;
            index++;
        }
        return -1;
    }
    //增長陣列長度
    public void ensureCapacity(int newSize) throws IllegalArgumentException{
        if(newSize<size)
            throw new IllegalArgumentException("引數無效:輸入長度必須大於等於陣列長度");
        else{
            Type[] temp = elements;   //儲存原資料
            elements = (Type[])Object[newSize];   //新建新陣列
            for(int i = 0;i<size;i++){
                elements[i] = temp[i];   //把原資料放入陣列
            }
        }
    }
    //將陣列長度變為資料實際長度
    public void trimToSize(){
        this.ensureCapacity(this.size);
    }
    //增長陣列長度
    public void addLength(int added) throws IllegalArgumentException{
        if(added<0)
            throw new IllegalArgumentException("引數無效:增長長度必須為正整數");
        else
            this.ensureCapacity(elements.length+added);
    }
    //在陣列末尾新增元素
    public void append(Type obj){
        if(size==elements.length) //陣列滿了
            this.ensureCapacity(elements.length*2);  //建立一個長度為原來兩倍的陣列
        elements[size] = obj;
        size++;
    }
    //在陣列指定位置插入
    public void insert(Type data,int index) throws IllegalArgumentException,IndexOutOfBoundsException{
        if(index<0||index>=elements.length)
            throw new IllegalArgumentException("引數無效:陣列索引必須為正整數且小於陣列長度");
        else if (index>=size)
            throw new IndexOutOfBoundsException("陣列越界:索引應小於等於陣列長度");
        else{
            if(size==elements.length)
                this.ensureCapacity(elements.length*2);
            for(int i=size;i>index;i--)
                elements[i] = elements[i-1];  //從末端移動 因為從索引開始移動會覆蓋資料 導致資料丟失
            elements[index] = data;
            size++;
        }
        
    }
    //刪除元素
    public void remove(int index) throws IllegalArgumentException,IndexOutOfBoundsException{
        if(index<0||index>=elements.length)
            throw new IllegalArgumentException("引數無效:陣列索引必須為正整數且小於陣列長度");
        else if (index>=size)
            throw new IndexOutOfBoundsException("陣列越界:索引應小於等於陣列長度");
        else{
            for(int i=index;i<size-1;i++) //i到size-2的時候已經移動size-1了
                elements[i] = elements[i+1];
            size--;
        }
        
    }
    //清空陣列
    public void clear(){
        elements = (Type[])new Object[DEFAULT_CAPACITY];
        size=0;
    }
    //判斷陣列是否為空
    public boolean isEmpty(){
        return size==0;
    }
    //返回陣列長度
    public int getSize(){
        return this.size;
    }
    //新建迭代器
    public Iterator<Type> iterator(){
        return new Iterator();
    }
    
    //繼承並實現迭代器
    private class Iterator<Type> implements Iterator<Type>{
        private int index = 0;
        private Type element;
        
        public boolean hasNext(){
            return current<getSize();
        }
        public Type next() throws NoSuchElementException{
            if(!hasNext())
                throw new NoSuchElementException("下標錯誤:沒有下一個元素了");
            return get(current++);
        }
        public void remove(){
            SequenceList.this.remove(current--);
        }
    }
}