• 利用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)
    
  • 相关阅读:
    扩散模型+文本生成
    期末总结
    查看笔记本电池损耗
    Qt数据可视化(散点图、折线图、柱状图、盒须图、饼状图、雷达图)开发实例
    24点游戏题库算法分析
    Qt项目开发实例 (含源码)
    Knowledge base for Interview
    System integration
    powerdesigner的使用
    VC++60MFC框架学习增加拖拽
  • 原文地址:https://www.cnblogs.com/chiyun/p/14061711.html
Copyright © 2020-2023  润新知