數(shù)據(jù)結(jié)構(gòu)與算法03 -- 動態(tài)數(shù)組

數(shù)組(Array)

  • 數(shù)組是一種順序存儲的線性表,所有元素的內(nèi)存地址是連續(xù)的;

自定義數(shù)組的接口設(shè)計

  • 要想實現(xiàn)一個數(shù)組的基本功能,通常情況下需要包含以下接口:
    • 數(shù)組中元素的數(shù)量;
    • 存儲元素的集合;
    • 添加元素至尾部;
    • 往指定index下標位置插入元素;
    • 返回指定index下標對應(yīng)的元素;
    • 刪除指定index下標位置的元素;
    • 清除所有元素;
    • 設(shè)置指定index下標位置的元素,會將之前的元素覆蓋,并返回之前的元素;
    • 根據(jù)元素獲取其index下標;
    • 獲取指定index下標的元素;
    • 判斷數(shù)組是否為空;
    • 判斷數(shù)組是否包含某個元素。
  • 上面所列出的所有功能接口,適用于所有的編程語言,這是一種編程的思想,可以使用不同的語言將其實現(xiàn),以后會考慮用OC語言再實現(xiàn)一遍;
  • 下面我們使用Java語言,自定義一個數(shù)組,由于缺乏Java的基礎(chǔ)知識,目前僅實現(xiàn)操作基礎(chǔ)數(shù)據(jù)類型int的數(shù)組,代碼實現(xiàn)如下:
package com.example.dynamicarray.ArrayList;
import java.util.Arrays;

public class YYArrayList {

    /**
     * 元素的數(shù)量
     */
    private int size;
    
    /**
     * 存儲所有元素的集合
     */
    private int[] elements;

    /**
     * 存儲元素的默認長度
     */
    private static final int DEFAULT_CAPACITY = 2;
    
    /**
     * 目標元素不存在,返回的默認下標index
     */
    private static final int ELEMENT_NOT_FOUND = -1;

    public YYArrayList(){
        //構(gòu)造函數(shù)之間的調(diào)用 用到this關(guān)鍵字
        this(DEFAULT_CAPACITY);
    }

    /**
     * 自定義構(gòu)造方法
     * @param capaticy 存儲元素的長度
     */
    public YYArrayList(int capaticy){
        capaticy = capaticy < DEFAULT_CAPACITY ? DEFAULT_CAPACITY : capaticy;
        //申請內(nèi)存空間
        elements = new int[capaticy];
    }

    /**
     * 返回數(shù)組元素的數(shù)量
     */
    public int size(){
        return size;
    }
    
    /**
     * 往數(shù)組添加目標元素
     * @param element 目標元素
     */
    public void addObject(int element){
        insertObjectAtIndex(size,element);
    }

    /**
     * 在指定index位置插入元素
     * @param index
     * @param element
     */
    public void insertObjectAtIndex(int index,int element){
        if (index < 0 || index > size){
            throw  new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
        }
        //檢測是否需要進行擴容
        ensureCapacity(size + 1);

        for (int i = size - 1;i >= index;i--){
            elements[i+1] = elements[I];
        }
        elements[index] = element;
        size++;
    }

    /**
     * 刪除指定index位置的元素,且返回被刪除的元素
     * @param index
     * @return
     */
    public int removeObjectAtIndex(int index){
        if (index < 0 || index >= size){
            throw  new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
        }
        int old = elements[index];
        for (int i = index + 1;i <= size - 1;i++){
            elements[i-1] = elements[I];
        }
        size--;
        return old;
    }
    
    /**
     * 清除所有元素
     */
    public void clear(){
        //將數(shù)組的size直接置為0,就不能訪問數(shù)組中的元素,相當于清空數(shù)組
        size = 0;
    }
    
    /**
     * 設(shè)置指定index位置的元素,且返回原來的元素
     * @param index 指定下標
     * @param element 新元素
     * @return 原來的元素
     */
    public int setObjectAtIndex(int index,int element){
        if (index < 0 || index >= size){
            throw  new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
        }
        int old = elements[index];
        elements[index] = element;
        return old;
    }
    
    /**
     * 查詢元素的index下標
     * @param element
     * @return
     */
    public int indexOfObject(int element){
        for (int i = 0;i < size;i++){
            if (elements[i] == element) return I;
        }
        return ELEMENT_NOT_FOUND;
    }

    /**
     * 獲取指定index下標的元素
     * @param index 指定下標
     * @return 目標元素
     */
    public int objectAtIndex(int index){
        //下標檢測,不符合時拋出異常
        if (index < 0 || index >= size){
            throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
        }
        return elements[index];
    }
    
    /**
     * 判斷數(shù)組是否為空
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 判斷是否包含某個元素
     * @param element 目標元素
     * @return
     */
    public boolean containsObject(int element){
        //判斷目標元素的index是否存在
        return indexOfObject(element) != ELEMENT_NOT_FOUND;
    }

    @Override
    public String toString() {
        StringBuffer string = new StringBuffer();
        string.append("size=").append(size).append(", [");
        for (int i = 0;i < size;i++){
            string.append(elements[I]);
            if (i != size - 1){
                string.append(", ");
            }
        }
        string.append("]");
        return string.toString();
    }

    /**
     * 保證要有capacity的容量 -- 涉及數(shù)組的擴容
     * @param capacity
     */
    private void ensureCapacity(int capacity){
        int oldCapacity = elements.length;
        //不需要擴容
        if (oldCapacity >= capacity) return;;

        //需要進行數(shù)組的擴容,新的容量大小是原來的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >>1);
        //重新申請內(nèi)存空間
        int[] newElements = new int[newCapacity];
        //將原來內(nèi)存空間上的元素賦值到新開辟的內(nèi)存空間中
        for (int i = 0;i < size;i++){
            newElements[i] = elements[I];
        }
        elements = newElements;
        System.out.println(oldCapacity + "擴容為" + newCapacity);
    }
}
  • 首先size屬性,是描述數(shù)組中元素的個數(shù);
  • elements屬性,是專門用來存儲數(shù)據(jù)元素的集合,需要進行初始化;
  • DEFAULT_CAPACITY是存儲數(shù)據(jù)元素集合的默認容量,
  • ELEMENT_NOT_FOUND當目標元素不存在,返回的默認下標index=-1;
  • YYArrayList()YYArrayList(int capaticy)是自定義數(shù)組YYArrayList的構(gòu)造方法,這里涉及到方法重載的技術(shù);
  • public int size():返回數(shù)組中的元素個數(shù);
  • public void addObject(int element):往數(shù)組中添加一個元素,內(nèi)部調(diào)用public void insertObjectAtIndex(int index,int element)函數(shù),在數(shù)組末尾添加一個元素;
  • public void insertObjectAtIndex(int index,int element):往數(shù)組指定index位置插入一個元素;首先對index進行了檢測,然后因為每次添加元素時,有可能數(shù)組的初始容量不夠用,需要對數(shù)組容量進行擴容,才能加入新的元素,內(nèi)部調(diào)用private void ensureCapacity(int capacity),在index位置插入了一個新元素,那么index位置之后的直到數(shù)組末尾的元素都要向后移動一個單位;最后數(shù)組的長度size+1;
  • public int removeObjectAtIndex(int index):移除指定index位置的元素且將移除元素返回;首先對index進行了檢測;然后刪除指定index位置的元素,那么index位置之后的直到數(shù)組末尾的元素都要向前移動一個單位;最后數(shù)組的長度size-1;
  • public void clear():清空數(shù)組元素,因為數(shù)組中存儲的是基本數(shù)據(jù)類型int,不涉及內(nèi)存管理,直接數(shù)組size屬性置為0即可,size置為0,外界就無法訪問數(shù)組中元素了,因為涉及index都做了檢測處理;
  • public int setObjectAtIndex(int index,int element):設(shè)置指定index位置的元素,就是替換元素,首先對index進行了檢測,然后替換,最后然后被替換的原來的元素;
  • public int indexOfObject(int element):查詢元素的index下標,遍歷數(shù)組,找到目標元素,返回index下標;
  • public int objectAtIndex(int index):獲取指定index位置的元素,首先對index進行了檢測,然后直接返回目標元素;
  • public boolean isEmpty():判斷數(shù)組元素是否為空,直接判斷size是否為0即可;
  • public boolean containsObject(int element):判斷數(shù)組是否包含某個元素,內(nèi)部直接調(diào)用public int indexOfObject(int element)函數(shù),通過是否存在index,來判斷是否存在元素;
  • public String toString():重寫打印方法;
  • private void ensureCapacity(int capacity):數(shù)組擴容保證數(shù)組容量足夠能加入新的元素;首先數(shù)組已經(jīng)存儲的元素個數(shù)(length)與當前數(shù)組容量(oldCapacity)進行比較,若oldCapacity>=length表明數(shù)組容量足夠,不需要擴容;否則需要進行數(shù)組擴容:
    • 確定新的容量newCapacity其大小是原來的1.5倍;
    • 重新創(chuàng)建一個以新的容量newCapacity的數(shù)組newElements,申請內(nèi)存空間;
    • 循環(huán)遍歷將原來內(nèi)存空間上的元素賦值到新開辟的內(nèi)存空間中;
    • 將數(shù)組的存儲集合elements指向新的數(shù)組newElements;
  • 外界測試代碼:
   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        YYArrayList array = new YYArrayList();
        array.addObject(10);
        array.addObject(20);
        array.addObject(30);
        array.addObject(40);
        array.addObject(50);
        Log.d("MainActivity",array.toString());

        array.removeObjectAtIndex(3);
        Log.d("MainActivity",array.toString());

        array.insertObjectAtIndex(3,88);
        Log.d("MainActivity",array.toString());

        array.setObjectAtIndex(3,99);
        Log.d("MainActivity",array.toString());

        int index = array.indexOfObject(50);
        Log.d("MainActivity","50的index下標 = " + index);

        int element = array.objectAtIndex(1);
        Log.d("MainActivity","index = 1的元素為:" + element);

    }
  • 打印結(jié)果:
Snip20210330_65.png
  • 上面自定義的數(shù)組YYArrayList,實現(xiàn)了操作int類型的基本功能,但是局限性很大,只能操作int,現(xiàn)在使用泛型這項技術(shù),將其改造成操作任意對象的數(shù)組;
  • 改造之后在代碼如下:
package com.example.dynamicarray.ArrayList;

public class YYArrayList <E> {

    /**
     * 元素的數(shù)量
     */
    private int size;
    /**
     * 存儲所有元素
     */
    private E[] elements;

    /**
     * 存儲元素的默認長度
     */
    private static final int DEFAULT_CAPACITY = 2;
    /**
     * 目標元素不存在,返回的默認下標index
     */
    private static final int ELEMENT_NOT_FOUND = -1;

    public YYArrayList(){
        //構(gòu)造函數(shù)之間的調(diào)用 用到this關(guān)鍵字
        this(DEFAULT_CAPACITY);
    }

    /**
     * 自定義構(gòu)造方法
     * @param capaticy 存儲元素的長度
     */
    public YYArrayList(int capaticy){
        capaticy = capaticy < DEFAULT_CAPACITY ? DEFAULT_CAPACITY : capaticy;
        //申請內(nèi)存空間
        elements = (E[])new Object[capaticy];
    }


    /**
     * 返回數(shù)組元素的數(shù)量
     */
    public int size(){
        return size;
    }

    /**
     * 往數(shù)組添加目標元素
     * @param element 目標元素
     */
    public void addObject(E element){
        insertObjectAtIndex(size,element);
    }

    /**
     * 在指定index位置插入元素
     * @param index
     * @param element
     */
    public void insertObjectAtIndex(int index,E element){
        if (element == null) return;
        if (index < 0 || index > size){
            throw  new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
        }
        //檢測是否需要進行擴容
        ensureCapacity(size + 1);

        for (int i = size - 1;i >= index;i--){
            elements[i+1] = elements[I];
        }
        elements[index] = element;
        size++;
    }

    /**
     * 刪除指定index位置的元素,且返回被刪除的元素
     * @param index
     * @return
     */
    public E removeObjectAtIndex(int index){
        if (index < 0 || index >= size){
            throw  new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
        }
        E old = elements[index];
        for (int i = index + 1;i <= size - 1;i++){
            elements[i-1] = elements[I];
        }
        elements[--size] = null;
        return old;
    }

    /**
     * 清除所有元素
     */
    public void clear(){
        //將數(shù)組中對象地址全部清空 -- 對象回收
        //數(shù)組沒有回收,可循環(huán)使用
        for (int i = 0; i < size;i++){
            elements[i] = null;
        }
        size = 0;
    }

    /**
     * 設(shè)置指定index位置的元素,且返回原來的元素
     * @param index 指定下標
     * @param element 新元素
     * @return 原來的元素
     */
    public E setObjectAtIndex(int index,E element){
        if (index < 0 || index >= size){
            throw  new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
        }
        E old = elements[index];
        elements[index] = element;
        return old;
    }


    /**
     * 獲取指定index下標的元素
     * @param index 指定下標
     * @return 目標元素
     */
    public E objectAtIndex(int index){
        //下標檢測,不符合時拋出異常
        if (index < 0 || index >= size){
            throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
        }
        return elements[index];
    }

    /**
     * 查詢元素的index下標
     * @param element
     * @return
     */
    public int indexOfObject(E element){
        if (element == null){
            for (int i = 0;i < size;i++){
                if (elements[i] == null) return I;
            }
        }else {
            for (int i = 0;i < size;i++){
                if (elements[i].equals(element)) return I;
            }
        }
        return ELEMENT_NOT_FOUND;
    }

    /**
     * 判斷數(shù)組是否為空
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 判斷是否包含某個元素
     * @param element 目標元素
     * @return
     */
    public boolean containsObject(E element){
        //判斷目標元素的index是否存在
        return indexOfObject(element) != ELEMENT_NOT_FOUND;
    }

    @Override
    public String toString() {
        StringBuffer string = new StringBuffer();
        string.append("size=").append(size).append(", [");
        for (int i = 0;i < size;i++){
            string.append(elements[I]);
            if (i != size - 1){
                string.append(", ");
            }
        }
        string.append("]");
        return string.toString();
    }

    /**
     * 保證要有capacity的容量
     * @param capacity
     */
    private void ensureCapacity(int capacity){
        int oldCapacity = elements.length;
        //不需要擴容
        if (oldCapacity >= capacity) return;

        //需要進行數(shù)組的擴容,新的容量大小是原來的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >>1);
        //重新申請內(nèi)存空間
        E[] newElements = (E[])new Object[newCapacity];
        //將原來內(nèi)存空間上的元素賦值到新開辟的內(nèi)存空間中
        for (int i = 0;i < size;i++){
            newElements[i] = elements[I];
        }
        elements = newElements;
        System.out.println(oldCapacity + "擴容為" + newCapacity);
    }
}
  • public class YYArrayList <E>其中<E>就是泛型,在設(shè)計YYArrayList數(shù)組的時候由于使用泛型這項技術(shù),使得YYArrayList可以存儲任意對象類型的數(shù)據(jù)元素,只有當真正使用YYArrayList的時候才去確定存儲元素的類型;
  • 在涉及元素類型的地方全部替換成泛型<E>
  • 定義存儲集合 private E[] elementselements = (E[])new Object[capaticy] 其中Object類在Java中是所有類的基類,用Object來定義數(shù)組則數(shù)組能存儲任意對象類型的元素,最后做了一個 (E[])強制類型轉(zhuǎn)換,要與聲明定義的數(shù)組類型保持一致;
  • public class YYArrayList <E>
  • public void clear():清除元素,需要做改動,因為我們現(xiàn)在存儲的是對象類型的元素,這就涉及到對象的內(nèi)存管理,詳細原理見附件1;所以需要將數(shù)組中所有指針全部置為null,則指針引用的對象才會回收,不會造成內(nèi)存泄漏。
  • public E removeObjectAtIndex(int index):移除指定index位置的元素,在遍歷移動之后,要將原來數(shù)組的最后一個指針清空,防止清除移動之后末尾元素被引用兩次;
  • 附件1:
Snip20210330_66.png
  • 定義了一個objects存儲Object類型的數(shù)組,初始容量為7;
  • objects在棧區(qū)分配內(nèi)存,new產(chǎn)生的數(shù)組對象在堆區(qū)分配內(nèi)存,且objects指向數(shù)組對象;數(shù)組中存儲的是對象的指針地址,而不是對象,我們通過對象的指針去訪問對象。
  • 對象的指針指向?qū)ο?,則對象不會被銷毀,若對象的指針清空為null,表明沒有外界去引用目標對象了,則對象就會被自動回收,這與OC中引用計數(shù)器類似。
  • 下面給出添加/移除指定index位置元素的圖表:
  • 初始圖:
Snip20210330_67.png
  • 在index = 2處插入元素88,操作原理圖如下:
Snip20210330_71.png
  • 在index = 2處移除元素30,操作原理圖如下:
Snip20210330_72.png
  • 外界調(diào)用代碼:定義了一個YYPerson類;
package com.example.dynamicarray.Bean;

import android.util.Log;

public class YYPerson {

    private int age;
    private String name;

    public YYPerson(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "YYPerson{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    /**
     * 對象銷毀時調(diào)用
     * @throws Throwable
     */
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        Log.d("Person:" + this.name,"finalize");
    }
}
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        YYPerson p1 = new YYPerson(20,"Tom");
        YYPerson p2 = new YYPerson(30,"John");
        YYPerson p3 = new YYPerson(40,"Jim");
        YYPerson p4 = new YYPerson(50,"Jack");

        //XSArrayList在實際使用的時候才確定元素的存儲類型為YYPerson
        XSArrayList<YYPerson> persons = new XSArrayList<>();
        persons.addObject(p1);
        persons.addObject(p2);
        persons.addObject(p3);
        persons.addObject(p4);
        System.out.println(persons);
        persons.removeObjectAtIndex(2);
        System.out.println(persons);
        persons.clear();
    }
  • 調(diào)試結(jié)果:
Snip20210330_70.png
  • Java對象銷毀時會調(diào)用finalize方法相當于OC中dealloc方法;
  • 數(shù)組清除,對象銷毀沒有造成內(nèi)存泄漏;

復(fù)雜度分析

  • 復(fù)雜度分析分三種情況:
    • 最好情況復(fù)雜度;
    • 最壞情況復(fù)雜度;
    • 平均情況復(fù)雜度;
  • public E objectAtIndex(int index):根據(jù)index獲取元素
public E objectAtIndex(int index) {
        rangeCheck(index);
        return elements[index];
    }
  • 復(fù)雜度為:常數(shù)階O(1)
  • public E setObjectAtIndex(int index, E element):設(shè)置index位置的元素;
public E setObjectAtIndex(int index, E element) {
        rangeCheck(index);
        E old = elements[index];
        elements[index] = element;
        return old;
    }
  • 復(fù)雜度為:常數(shù)階O(1);
  • public void insertObjectAtIndex(int index, E element):往指定index位置插入元素;
public void insertObjectAtIndex(int index, E element) {
        if (element == null) return;
        rangeCheckForInsert(index);
        //檢測是否需要進行擴容
        ensureCapacity(size + 1);

        for (int i = size - 1;i >= index;i--){
            elements[i+1] = elements[I];
        }
        elements[index] = element;
        size++;
    }
  • 數(shù)據(jù)規(guī)模為size;
  • 最好情況復(fù)雜度:index = size時,即往尾部插入元素,其復(fù)雜度為O(1);
  • 最壞情況復(fù)雜度:index = 0時,即往首位置插入元素,其復(fù)雜度為O(n);
  • 平均情況復(fù)雜度:其復(fù)雜度為O(n);
  • public E removeObjectAtIndex(int index):移除指定index位置的元素;
public E removeObjectAtIndex(int index) {
        rangeCheck(index);
        E old = elements[index];
        for (int i = index + 1;i <= size - 1;i++){
            elements[i-1] = elements[I];
        }
        elements[--size] = null;
        return old;
    }
  • 數(shù)據(jù)規(guī)模為size;
  • 最好情況復(fù)雜度:index = size時,即往尾部插入元素,其復(fù)雜度為O(1);
  • 最壞情況復(fù)雜度:index = 0時,即往首位置插入元素,其復(fù)雜度為O(n);
  • 平均情況復(fù)雜度:其復(fù)雜度為O(n);
  • 當數(shù)組出現(xiàn)擴容的時候,復(fù)雜度會猛然上升,像這種經(jīng)過連續(xù)的多次復(fù)雜度比較低的情況后,出現(xiàn)個別復(fù)雜度比較高的情況,使用均攤復(fù)雜度;

動態(tài)數(shù)組的縮容

  • 當內(nèi)存空間使用比較緊張,動態(tài)數(shù)組有比較多的剩余空間,可以考慮進行縮容操作;
  • 比如剩余空間占總?cè)萘康囊话霑r,就進行縮容;
  • public E removeObjectAtIndex(int index)中調(diào)用縮容方法,實現(xiàn)如下:
/**
     * 當內(nèi)存空間使用比較緊張,動態(tài)數(shù)組有比較多的剩余空間,可以考慮進行縮容
     * 當剩余空間占總?cè)萘康囊话霑r,就進行縮容;
     */
    private void trim(){
        int oldCapacity = elements.length;
        int newCapacity = oldCapacity >> 1;
        if (size >= newCapacity || oldCapacity <= DEFAULT_CAPACITY) return;

        //重新申請內(nèi)存空間
        E[] newElements = (E[])new Object[newCapacity];
        //將原來內(nèi)存空間上的元素賦值到新開辟的內(nèi)存空間中
        for (int i = 0;i < size;i++){
            newElements[i] = elements[I];
        }
        elements = newElements;
        System.out.println(oldCapacity + "縮容為" + newCapacity);
    }
  • 調(diào)用代碼:
public E removeObjectAtIndex(int index) {
        rangeCheck(index);
        E old = elements[index];
        for (int i = index + 1;i <= size - 1;i++){
            elements[i-1] = elements[I];
        }
        elements[--size] = null;
        //數(shù)組縮容
        trim();
        return old;
    }
  • 在清空數(shù)組的時候,如果數(shù)組內(nèi)部集合的容量過大,也需要進行縮容處理,代碼實現(xiàn)如下:
@Override
    public void clear() {
        //將數(shù)組中對象地址全部清空 -- 對象回收
        //數(shù)組沒有回收,可循環(huán)使用
        for (int i = 0; i < size;i++){
            elements[i] = null;
        }
        size = 0;

        //清空數(shù)組元素時,縮小數(shù)據(jù)集合的容量
        if (elements != null && elements.length > DEFAULT_CAPACITY){
            elements = (E[])new Object[DEFAULT_CAPACITY];
        }
    }
  • 測試代碼:
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        YYArrayList array = new YYArrayList(6);
        array.addObject(1);
        array.addObject(2);
        array.addObject(3);
        array.addObject(4);
        array.addObject(5);
        array.addObject(6);
        System.out.println(array);
        array.addObject(7);
        array.addObject(8);
        array.addObject(9);
        array.addObject(10);
        array.removeObjectAtIndex(2);
        array.removeObjectAtIndex(2);
        array.removeObjectAtIndex(2);
        array.removeObjectAtIndex(2);
        array.removeObjectAtIndex(2);
        System.out.println(array);
    }
  • 調(diào)試結(jié)果:
Snip20210401_94.png
  • 若動態(tài)數(shù)組的擴容倍數(shù),縮容倍數(shù)設(shè)計不得當,有可能造成復(fù)雜度的震蕩;
Snip20210401_95.png
  • 數(shù)組初始容量為4;
  • 擴容與縮容都是原來容量的兩倍;
  • 那么當在添加元素55時,數(shù)組擴容,復(fù)雜度由O(1),變成O(n);
  • 當再次刪除元素55時,數(shù)組縮容,復(fù)雜度O(n),再刪除元素44,復(fù)雜度變成O(1);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容