Python自定义实现列表--基于数组和双向循环链表两种方式

前言

学习过Python 的肯定知道Python内置了List()抽象数据结构。不过,本篇博客在于自定义实现列表。
这里,通过底层数据结构数组和链表来实现。
其中数组是基于Python内置的List实现,链表过自定义node对象实现。

文件结构:
在这里插入图片描述
完整代码可见GitHub:
https://github.com/GYT0313/Python-DataStructure/tree/master/7-list/list

1. 超类

无论是基于数组还是链表,这里给出了两者的超类。
abstractcollection.py

"""
File: abstractcollection.py
Author: Ken Lambert
"""

class AbstractCollection(object):
    """An abstract collection implementation."""

    # Constructor
    def __init__(self, sourceCollection = None):
        """Sets the initial state of self, which includes the
        contents of sourceCollection, if it's present."""
        self._size = 0
        if sourceCollection:
            if type(sourceCollection) == int:
                self.add(sourceCollection)
            else:
                for item in sourceCollection:
                    self.add(item)

    # Accessor methods
    def isEmpty(self):
        """Returns True if len(self) == 0, or False otherwise."""
        return len(self) == 0
    
    def __len__(self):
        """Returns the number of items in self."""
        return self._size

    def __str__(self):
        """Returns the string representation of self."""
        return "[" + ", ".join(map(str, self)) + "]"

    def __add__(self, other):
        """Returns a new bag containing the contents
        of self and other."""
        result = type(self)(self)
        for item in other:
            result.add(item)
        return result

    def __eq__(self, other):
        """Returns True if self equals other,
        or False otherwise."""
        if self is other: return True
        if type(self) != type(other) or \
           len(self) != len(other):
            return False
        otherIter = iter(other)
        for item in self:
            if item != next(otherIter):
                return False
        return True

abstractlist.py

"""
File: abstractlist.py
"""

from abstractcollection import AbstractCollection
class AbstractList(AbstractCollection):
    """抽象列表的实现"""

    def __init__(self, source_collection):
        self._mod_count = 0
        AbstractCollection.__init__(self, source_collection)

    def get_mod_count(self):
        """返回修改计数"""
        return self._mod_count

    def inc_mod_count(self):
        """增加修改计数"""
        self._mod_count += 1

    def index(self, item):
        """查找指定item 的索引"""
        position = 0
        for data in self:
            if data == item:
                return position
            else:
                position += 1
        if position == len(self):
            return ValueError(str(item) + " not in list.")

    def add(self, item):
        """增加元素"""
        self.insert(len(self), item)

    def remove(self, item):
        """删除"""
        position = self.index(item)
        self.pop(position)

2. 基于数组实现

运行示例:
在这里插入图片描述

代码:
arrays.py

"""
File: arrays.py

An Array is a restricted list whose clients can use
only [], len, iter, and str.

To instantiate, use

<variable> = array(<capacity>, <optional fill value>)

The fill value is None by default.
"""

class Array(object):
    """Represents an array."""

    def __init__(self, capacity, fillValue = None):
        """Capacity is the static size of the array.
        fillValue is placed at each position."""
        self._items = list()
        for count in range(capacity):
            self._items.append(fillValue)

    def __len__(self):
        """-> The capacity of the array."""
        return len(self._items)

    def __str__(self):
        """-> The string representation of the array."""
        return str(self._items)

    def __iter__(self):
        """Supports iteration over a view of an array."""
        return iter(self._items)

    def __getitem__(self, index):
        """Subscript operator for access at index."""
        return self._items[index]

    def __setitem__(self, index, newItem):
        """Subscript operator for replacement at index."""
        self._items[index] = newItem

arraylist.py

""""
File: arraylist.py
"""

from arrays import Array
from abstractlist import AbstractList
from arraylistiterator import ArrayListIterator

class ArrayList(AbstractList):
    """基于数组实现列表"""

    DEFAULT_CAPACITY = 10

    def __init__(self, source_collection=None):
        self._items = Array(ArrayList.DEFAULT_CAPACITY)
        AbstractList.__init__(self, source_collection)

    def __iter__(self):
        """迭代"""
        cursor = 0
        while cursor < len(self):
            yield self._items[cursor]
            cursor += 1

    def __getitem__(self, i):
        """获取i 位置的元素"""
        if i < 0 or i >= len(self):
            raise IndexError("List index out of range.")
        return self._items[i]

    def __setitem__(self, i, item):
        """修改操作"""
        if i < 0 or i >= len(self):
            raise IndexError("List index out of range.")
        self._items[i] = item

    def insert(self, i, item):
        """在i 位置插入item"""
        if i < 0:
            i = 0
        elif i > len(self):
            i = len(self)
        if i < len(self):
            # 将数组元素从右往左, 依次后移
            for j in range(len(self), i, -1):
                self._items[j] = self._items[j - 1]
        self._items[i] = item
        self._size += 1
        self.inc_mod_count()

    def pop(self, i=None):
        """删除i 位置元素"""
        if i == None:
            i = len(self) - 1
        if i < 0 or i >= len(self):
            raise IndexError("List index out of range.")
        item = self._items[i]
        # 从左往右,移动元素
        for j in range(i, len(self) - 1):
            self._items[j] = self._items[j + 1]
        self._size -= 1
        self.inc_mod_count()
        return item

    def list_iterator(self):
        """返回列表迭代器"""
        return ArrayListIterator(self)

在此基础上增加列表迭代器

运行示例:
在这里插入图片描述
在这里插入图片描述

代码:
arraylistiterator.py

"""
File: arraylistiterator.py
"""


class ArrayListIterator(object):
    """基于数组的列表迭代器"""

    def __init__(self, backing_store):
        # backing_store 和 mod_count 都是array_list的同一个对象(浅拷贝)
        self._backing_store = backing_store
        self._mod_count = backing_store.get_mod_count()
        self.first()

    def first(self):
        """将cursor 重置为开头"""
        self._cursor = 0
        # 调用next 或 previous 前指向的节点位置的参数,默认值=-1
        # 改参数用于调用修改器方法时修改的位置索引
        self._last_item_pos = -1

    def has_next(self):
        """如果当前cursor之后还有元素返回True"""
        return self._cursor < len(self._backing_store)

    def next(self):
        """返回当前cursor的元素, 并且cursor 后移"""
        if self.has_next() == False:
            raise ValueError("No next item in list iterator.")
        if self._mod_count != self._backing_store.get_mod_count():
            raise AttributeError(
                "Illegal modification of backing store.")
        self._last_item_pos = self._cursor
        self._cursor += 1
        return self._backing_store[self._last_item_pos]

    def last(self):
        """将cursor 重置为末尾之后"""
        self._cursor = len(self._backing_store)
        self._last_item_pos = -1

    def has_previous(self):
        """如果当前cursor 之前还有元素返回True"""
        return self._cursor > 0

    def previous(self):
        """返回当前cursor 的前一个元素, 并且cursor 前移"""
        if self.has_previous() == False:
            raise ValueError("No previous item in list iterator.")
        if self._mod_count != self._backing_store.get_mod_count():
            raise AttributeError(
                "Illegal modification of backing store.")
        self._cursor -= 1
        self._last_item_pos = self._cursor
        return self._backing_store[self._last_item_pos]


    """3个修改器方法"""
    def replace(self, item):
        """替换最后一次修改的位置为 item"""
        if self._last_item_pos == -1:
            raise AttributeError(
                "The current position is undefined.")
        if self._mod_count != self._backing_store.get_mod_count():
            raise AttributeError(
                "List has been modified illegally.")
        self._backing_store[self._last_item_pos] = item
        self._last_item_pos = -1

    def insert(self, item):
        """在最后修改的位置插入 item"""
        if self._mod_count != self._backing_store.get_mod_count():
            raise AttributeError(
                "List has been modified illegally.")
        # 没有调用next或previous 默认添加到末尾
        if self._last_item_pos == -1:
            self._backing_store.add(item)
        else:
            self._backing_store.insert(self._last_item_pos, item)
        self._last_item_pos = -1
        self._mod_count += 1

    def remove(self):
        """删除最后修改的位置"""
        if self._last_item_pos == -1:
            raise AttributeError(
                "The current position is undefined.")
        if self._mod_count != self._backing_store.get_mod_count():
            raise AttributeError(
                "List has been modified illegally.")
        item = self._backing_store.pop(self._last_item_pos)
        # 如果之前调用的是next,代表cursor > last_item_pos
        # 所以当删除last_item_pos 位置后,cursor 需要 -1
        if self._last_item_pos < self._cursor:
            self._cursor -= 1
        self._mod_count += 1
        self._last_item_pos = -1

3. 基于双向循环链表实现

运行示例:
在这里插入图片描述
代码:
linkedlist.py

"""
File: linkedlist.py
"""


from node import DoubleNode
from abstractlist import AbstractList
from linkedlistiterator import LinkedListIterator
import copy

class LinkedList(AbstractList):
    """基于双向循环链表实现列表"""

    def __init__(self, source_collection=None):
        # head 指向哨兵节点, 而不是数据节点,
        self._head = DoubleNode()
        self._head.previous = self._head
        AbstractList.__init__(self, source_collection)

    def __iter__(self):
        """迭代"""
        if self.isEmpty():
            return []
        # cursor指向第一个数据节点
        cursor = self._head.next
        while cursor != self._head:
            yield cursor.data
            cursor = cursor.next

    def _get_node(self, i):
        """返回索引为i 的节点"""
        if i == len(self):
            return self._head
        if i == len(self) - 1:
            return self._head.previous
        probe = self._head.next
        while i > 0:
            probe = probe.next
            i -= 1
        return probe

    def __setitem__(self, i, item):
        """重新赋值i 节点"""
        if i < 0 or i >= len(self):
            raise IndexError("List index out of range.")
        self._get_node(i).data = item

    def __getitem__(self, i):
        """返回i 节点的值"""
        if i < 0 or i >= len(self):
            raise IndexError("List index out of range.")
        return self._get_node(i).data

    def insert(self, i, item):
        """插入"""
        if i < 0:
            i = 0
        elif i > len(self):
            i = len(self)
        the_node = self._get_node(i)
        new_node = DoubleNode(item, the_node.previous, the_node)
        the_node.previous.next = new_node
        the_node.previous = new_node
        self._size += 1

    def pop(self, i):
        """删除i 位置"""
        if i < 0 or i >= len(self):
            raise IndexError("List index out of range.")
        the_node = self._get_node(i)
        the_node.next.previous = the_node.previous
        the_node.previous.next = the_node.next
        return the_node.data

    def list_iterator(self):
        """返回列表迭代器"""
        return LinkedListIterator(self)

同样在此基础上实现链表迭代器

不过,同样按照核数组列表迭代器一样,进行_mod_count 检验,但是却无法实现列表和列表迭代器+1 的同步操作。所以这里不再使用_mo_count 验证。
运行示例:
在这里插入图片描述
代码:
linkedlistiterator.py

"""
File: linkedlistiterator.py
"""

from node import DoubleNode

class LinkedListIterator(object):
    """基于双向循环链表的列表迭代器"""

    def __init__(self, backing_sotre):
        # backing_store 和 mod_count 都是array_list的同一个对象(浅拷贝)
        self._backing_store = backing_sotre
        self._head = backing_sotre._head
        self.first()

    def first(self):
        """将cursor 重置为开头"""
        # cursor指向第一个数据节点
        self._cursor = self._head.next
        # 调用next 或 previous 前指向的节点位置
        self._last_item_pos = self._head

    def has_next(self):
        """如果当前cursor之后还有节点返回True"""
        return self._cursor != self._head

    def next(self):
        """返回当前cursor的节点, 并且cursor 后移"""
        if self.has_next() == False:
            raise ValueError("No next item in list iterator.")
        self._last_item_pos = self._cursor
        self._cursor = self._cursor.next
        return self._last_item_pos.data

    def last(self):
        """将cursor 重置为末尾之后"""
        self._cursor = self._head
        self._last_item_pos = self._head

    def has_previous(self):
        """如果当前cursor 之前还有节点返回True"""
        return self._cursor != self._head

    def previous(self):
        """返回当前cursor 的前一个节点, 并且cursor 前移"""
        if self.has_previous() == False:
            raise ValueError("No previous item in list iterator.")
        self._cursor = self._cursor.previous
        self._last_item_pos = self._cursor
        return self._last_item_pos.data

    """3个修改器方法"""
    def replace(self, item):
        """替换最后一次修改的位置为 item"""
        if self._last_item_pos == self._head:
            raise AttributeError(
                "The current position is undefined.")
        self._last_item_pos.data = item
        self._last_item_pos = self._head

    def insert(self, item):
        """在最后修改的位置插入 item"""
        new_node = DoubleNode(item, 
            self._last_item_pos.previous, self._last_item_pos)
        self._last_item_pos.previous.next = new_node
        self._last_item_pos.previous = new_node
        self._last_item_pos = self._head

    def remove(self):
        """删除最后修改的位置"""
        if self._last_item_pos == self._head:
            raise AttributeError(
                "The current position is undefined.")
        self._last_item_pos.previous.next = self._last_item_pos.next
        self._last_item_pos.next.previous = self._last_item_pos.previous
        self._last_item_pos = self._head

代码可见GitHub:
https://github.com/GYT0313/Python-DataStructure/tree/master/7-list/list

完!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值