利用python實現動態數組


一、數組

說動態數組之前,首先要說數組,數組是一種順序存儲的線性表,所有元素的內存地址都是連續的。數組的最大優點是他的查找時間復雜度能夠達到O(1),但是增和刪的時間復雜度較高O(n)

二、動態數組

動態數組,即根據用戶的輸入動態擴充或縮小當前數組的容量。在python中,已經內置了動態數組,叫做列表,List

下面是利用python代碼實現動態數組的增刪改查操作。

# ArrryList.py
class Arr:
    # 設置兩個常亮,分別是默認容量大小與未找到元素返回的值
    DEFAULT_CAPACITY = 10
    ELEMENT_NOT_FOUND = -1

    # 初始化,若用戶未指定數組大小或者小於默認,直接使用默認容量,否則容量為用戶指定
    def __init__(self, capacity=DEFAULT_CAPACITY):
        capacity = self.DEFAULT_CAPACITY if capacity < self.DEFAULT_CAPACITY else capacity
        self._capacity = capacity
        self._size = 0
        self._elements = [None] * self._capacity

    def size(self):
        return self._size

    def is_empty(self):
        # return True if self._size == 0 else False
        # 改進上面這還代碼,因為在python中所有值都可以轉布爾,所以利用隱式布爾值
        return self._size == 0

    # 查看元素是否存在--->bool
    def contains(self, element):
        # if self.index_of(element):
        #     return True
        # return False

        return True if self.index_of(element) else False

    # 根據索引添加,添加結束后判斷是否需要擴容
    def add(self, index, element):
        self._out_of_index(index)
        self._size = i = self._size + 1
        while i >= index:
            self._elements[i] = self._elements[i - 1]
            i -= 1
        self._elements[index] = element
        self._expend_capacity()

    # 數組末尾追加,添加結束后判斷是否需要擴容
    def add_last(self, element):
        self._out_of_index(self._size)
        self._elements[self._size] = element
        self._size += 1
        self._expend_capacity()

    # 根據索引取值
    def get(self, index):
        self._out_of_index(index)
        return self._elements[index]

    # 根據索引改值
    def set(self, index, element):
        self._out_of_index(index)
        self._elements[index] = element

    # 刪除元素,若用戶未指定參數,默認刪除最后一個元素,刪除后判斷是否要縮容
    def remove(self, index=ELEMENT_NOT_FOUND):
        self._out_of_index(index)
        if index == self.ELEMENT_NOT_FOUND:
            self._remove_last()

        # 刪除元素后,該索引后的每個元素都要往前移一格,然后數組大小減一
        i = index
        while i <= self._size:
            self._elements[i] = self._elements[i + 1]
            i += 1
        self._size -= 1
        self._reduce_capacity()

    # 返回第一個匹配傳入值的索引
    def index_of(self, element):
        for index in range(self._size + 1):
            if element == self._elements[index]:
                return index
        return self.ELEMENT_NOT_FOUND

    def clear(self):
        self._size = 0
        return self._size

    # 判斷索引是否越界
    def _out_of_index(self, index):
        if index < 0 or index > self._size + 1:
            raise IndexError('index out of range')

    # 當容量不夠時動態擴容,默認為擴大為原來的1.5倍
    def _expend_capacity(self):
        # 當size小於容量,直接返回,當size正好等於容量,需要擴容
        if self._size < self._capacity - 1:
            return

        self._capacity = self._capacity * 2
        self._new_elements = [None] * self._capacity
        for i in range(self._size):
            self._new_elements[i] = self._elements[i]

        self._elements = self._new_elements

    # 動態縮容,默認縮小到當前的一半
    def _reduce_capacity(self):
        # 當size小於默認容量或者大於當前容量的一半時直接返回
        if self._size <= self._capacity or self._size > (self._capacity // 2):
            return

        self._capacity = (self._capacity // 2).__ceil__()
        for i in range(self._size):
            self._new_elements[i] = self._elements[i]

        self._elements = self._new_elements

    def __str__(self):
        arrlist = ''
        num = 0

        for i in self._elements:
            if num == self._size:
                break
            arrlist = arrlist + str(i) + ','
            num += 1

        arrlist = arrlist.strip(",")
        arrlist = '[' + arrlist + ']'
        return arrlist

    """
    刪除最后一個元素,因為最后一個元素也是往前移動一格,雖然size-1,但是其實最后一個元素引用了兩次,
    即當前的數組末尾加上原來位置的引用,無法回收,所以對於最后一個元素要手動設置為None
    """

    def _remove_last(self):
        self._size -= 1
        self._elements[self._size] = None
        self._reduce_capacity()

# 測試文件,test.py
if __name__ == '__main__':
    from ArrayList import Arr
    a = Arr()
    # a = a  #type:Arr
    a.add_last(11)
    a.add_last(22)
    a.add_last(33)
    a.add_last(44)
    a.add_last('55')
    a.add_last(66)
    a.add_last(77)
    a.add_last(88)
    a.add_last(99)
    # a.add(2,'st')
    # a.remove(2)
    # print(a.size())
    # print(a.is_empty())
    # print(a.contains('55'))
    # print(a.index_of(99))
    # print(a.get(789))
    # a.set(-1,99)
    # a.clear()

    print(a)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM