0
点赞
收藏
分享

微信扫一扫

python 数据结构之 双向链表 的定义以及类函数的定义:

mafa1993 2022-04-14 阅读 62

python 数据结构之 双向链表 的定义以及类函数的定义:
在这里插入图片描述

class Node(object):
    def __init__(self, data, prev_node=None, next_node=None):
        self.data = data
        self.prev_node = prev_node
        self.next_node = next_node

    def __repr__(self):
        return str(self.data)


class DoublyLinkedList(object):
    def __init__(self):
        self.head = None
        self.__count = 0

    def is_empty(self):
        return self.head is None

    def __len__(self):
        return self.__count

    def add(self, data):
        """
        Adds new Node containing data to head of the list
        Also called prepend
        Takes O(1) time
        """
        new_head = Node(data, prev_node=None, next_node=self.head)
        if not self.is_empty():
            self.head.prev_node = new_head

        self.head = new_head
        self.__count += 1

    def search(self, key):
        """
        Search for the first node containing data that matches the key
        Returns the node or `None` if not found
        Takes O(n) time
        """
        current = self.head
        while current:
            if current.data == key:
                return current
            else:
                current = current.next_node
        return None

    def node_at_index(self, index):
        """
        Returns the Node at specified index
        Takes O(n) time
        """
        if index >= self.__count:
            raise IndexError('index out of range')
        if index == 0:
            return self.head

        current = self.head
        '''
        position = 0
        while position < index:
            current = current.next_node
            position += 1
        '''
        while index:
            current = current.next_node
            index -= 1

        return current

    def insert(self, data, index):
        """
        Inserts a new Node containing data at index position
        Insertion takes O(1) time but finding node at insertion point takes
        O(n) time.
        Takes overall O(n) time.
        """
        if index >= self.__count:
            raise IndexError('index out of range')
        if index == 0:
            self.add(data)
            return
        if index > 0:
            current_node = self.node_at_index(index)
            prev_node = current_node.prev_node
            new_node = Node(data, prev_node=prev_node, next_node=current_node)
            current_node.prev_node = new_node
            prev_node.next_node = new_node

        self.__count += 1

    def remove(self, key):
        """
        Removes Node containing data that matches the key
        Returns the node or `None` if key doesn't exist
        Takes O(n) time
        """
        current = self.head
        found = False
        while current and not found:
            if current.data == key and current is self.head:
                found = True
                self.head = current.next_node
                self.head.prev_node = None
                self.__count -= 1
                return current
            elif current.data == key:
                found = True
                prev_node = current.prev_node
                next_node = current.next_node
                prev_node.next_node = next_node
                next_node.prev_node = prev_node
                self.__count -= 1
                return current
            else:
                current = current.next_node

    def remove_at_index(self, index):
        """
        Removes Node at specified index
        Takes O(n) time
        """
        if index >= self.__count:
            raise IndexError('index out of range')

        current = self.head
        if index == 0:
            self.head = current.next_node
            self.head.prev_node = None
            self.__count -= 1
            return current

        current = self.node_at_index(index)
        prev_node = current.prev_node
        next_node = current.next_node
        prev_node.next_node = next_node
        next_node.prev_node = prev_node

        self.__count -= 1

        return current

    def __iter__(self):
        current = self.head
        while current:
            yield current
            current = current.next_node

    def __repr__(self):
        """
        Return a string representation of the list.
        Takes O(n) time.
        """
        nodes = []
        current = self.head
        while current:
            if current is self.head:
                nodes.append("[Head: %s]" % current.data)
            elif current.next_node is None:
                nodes.append("[Tail: %s]" % current.data)
            else:
                nodes.append("[%s]" % current.data)
            current = current.next_node
        return  ' <=> '.join(nodes)


if __name__ == '__main__':
    dll_1 = DoublyLinkedList()
    dll_1.add(1)
    dll_1.add(2)
    dll_1.add(3)
    dll_1.add(4)
    dll_1.insert(5, 2)
    print(dll_1)



运行结果:

[Head: 4] <=> [3] <=> [5] <=> [2] <=> [Tail: 1]
举报

相关推荐

0 条评论