Python實現列表和鏈表


Python實現列表和鏈表

list[index]                      O(1)
list.append                      O(1)
list.insert                      O(n)
list.pop(index) 默認刪last        O(1)
list.remove(element)             O(n)        

class Array(object):
    def __init__(self, size=32):
        self._size = size
        self._items = [None] * self._size

    def __getitem__(self, index):
        return self._items[index]

    def __setitem__(self, index, value):
        self._items[index] = value

    def __len__(self):
        return self._size

    def clear(self, value=None):
        for i in range(len(self._items)):
            self._items[i] = value

    def __iter__(self):
        for item in self._items:
            yield item

單鏈表

缺點:1. remove時是O(n) 2.只能單向遍歷

linked_list.append(value)           O(1)
linked_list.appendleft(value)       O(1)
linked_list.find(value)             O(n)
linked_list.remove(value)           O(n)

class Node(object):
    def __init__(self, value=None, next=None):
        self.value, self.next = value, next


class LinkedList(object):
    def __init__(self, msxsize=None):
        # msxsize=None代表無限大
        self.maxsize = msxsize
        # self.root 是根節點,根節點的next一般指向頭節點head節點
        self.root = Node()
        self.length = 0
        # self.tailnode表示最后一個節點
        self.tailnode = None

    def __len__(self):
        return self.length

    def append(self, value):
        # 判斷當前最大值是否超過了允許的最大值
        if self.maxsize is not None and len(self) > self.maxsize:
            raise Exception("Full")
        node = Node(value)
        tailnode = self.tailnode
        if tailnode is None:
            # 表明現在只有一個root節點, 然后指向當前的node節點即可
            self.root.next = node
        else:
            # 否則把最后一個節點的next指向當前的node節點
            self.tailnode.next = node
        # 更新最后一個節點為node,因為我們把node放到了最后,而self.tailnode代表最后一個節點,所以要更新
        self.tailnode = node
        # 鏈表長度加一
        self.length += 1

    def appendleft(self, value):
        # 定義頭節點
        headnode = self.root.next
        node = Node(value)
        # 根節點指向新的head節點: node節點
        self.root.next = node
        # node節點指向之前的head節點
        node.next = headnode
        self.length += 1

    def iter_node(self):
        # 第一個節點
        curnode = self.root.next
        # 當前節點不是最后一個節點時
        while curnode is not self.tailnode:
            yield curnode
            # 當前節點更新為下一個節點
            curnode = curnode.next
        # 尋找到最后節點時,也需要把最后一個節點yield出來
        yield curnode

    def __iter__(self):
        for node in self.iter_node():
            yield node.value

    def remove(self, value):
        """
        刪除包含值的一個節點,將其前一個節點的next指向下一個節點即可  O(n)
        :param value:
        :return:
        """
        # 根節點
        prevnode = self.root
        for curnode in self.iter_node():
            if curnode.value == value:
                prevnode.next = curnode.next
                if curnode is self.tailnode:
                    # 注意更新 tailnode
                    self.tailnode = prevnode
                del curnode
                self.length -= 1
                # 返回1代表成功
                return 1
            else:
                # 更新 prevnode
                prevnode = curnode
        # 返回-1表示刪除失敗
        return -1

    def find(self, value):
        # O(n)
        index = 0
        for node in self.iter_node():
            if node.value == value:
                return index
            index += 1
        # 返回-1表示沒找到
        return -1

    def popleft(self):
        # O(1)
        if self.root.next is None:
            raise Exception("pop from empty LinkedList")
        headnode = self.root.next
        # 根節點指向頭節點的下一個節點
        self.root.next = headnode.next
        value = headnode.value
        self.length -= 1
        del headnode
        return value

    def clear(self):
        for node in self.iter_node():
            del node
        self.root.next = None
        self.length = 0

雙端鏈表

class Node(object):
    def __init__(self, value=None, prev=None, next=None):
        self.value, self.prev, self.next = value, prev, next


class CirculaDoubleLinkedList(object):
    def __init__(self, msxsize=None):
        # msxsize=None代表無限大
        self.maxsize = msxsize
        node = Node()
        node.next, node.prev = node, node
        self.root = node
        self.length = 0

    def __len__(self):
        return self.length

    def headnode(self):
        return self.root.next

    def tailnode(self):
        # 根節點的prev指向尾節點
        return self.root.prev

    def append(self, value):
        # 判斷當前最大值是否超過了允許的最大值
        if self.maxsize is not None and len(self) > self.maxsize:
            raise Exception("Full")
        node = Node(value=value)
        tailnode = self.tailnode()
        # 最后一個節點指向新的最后節點
        tailnode.next = node
        # 新的最后節點指向前節點
        node.prev = tailnode
        # node的下一個節點指向root
        node.next = self.root
        # 根節點的上一個節點指向新的最后節點,形成閉環
        self.root.prev = node
        self.length += 1

    def appendleft(self, value):
        # 判斷當前最大值是否超過了允許的最大值
        if self.maxsize is not None and len(self) > self.maxsize:
            raise Exception("Full")
        node = Node(value=value)
        # 如果根節點的下一個節點是自己,則證明是空的
        if self.root.next is self.root:
            # 新節點的下一個指向根節點
            node.next = self.root
            # 新節點的上一個指向根節點
            node.prev = self.root
            # 根節點的下一個指向新節點
            self.root.next = node
            # 根節點的上一個指向新節點
            self.root.prev = node
        else:
            # 新節點的上一個節點指向根節點
            node.prev = self.root
            # 獲取頭節點
            headnode = self.headnode()
            # 新節點的下一個指向頭節點
            node.next = headnode
            # 頭節點的上一個指向新節點
            headnode.prev = node
            # 根節點的下一個指向新節點
            self.root.next = node
            self.length+=1

    def remove(self, node):
        # O(1)  node is not value
        if node is self.root:
            return
        else:
            # 被刪除節點的上一個節點的next指向被刪除節點的下一個節點
            node.prev.next = node.next
            # 被刪除節點的下一個節點的prev指向被刪除節點的上一個節點
            node.next.prev = node.prev
        self.length -= 1
        return node

    def iter_node(self):
        if self.root.next is self.root:
            return
        curnode = self.root.next
        while curnode is not self.root:
            yield curnode
            curnode = curnode.next
        yield curnode

    def __iter__(self):
        for node in self.iter_node():
            yield node.value

    def iter_node_reverse(self):
        if self.root.next is self.root:
            return
        curnode = self.root.prev
        while curnode is not self.root:
            yield curnode
            curnode = curnode.prev
        yield curnode


免責聲明!

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



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