数据结构二:python实现简单的双向链表

1.双向链表的结点只是比单向链表的结点多一个属性前置结点

这里双向结点的类继承了(上一篇)单向链表使用的结点的类

class DoubleLinkedNode(BaseNode):
    """
    双向链接结点
    """
    def __init__(self, item):
        """双向链表的结点,就是比单向链表多一个前置结点的属性"""
        # 前置结点
        self.pre = None
        super(DoubleLinkedNode, self).__init__(item)

2.双向链表的操作:

如果不涉及增、删操作,和单向链表的操作一致

这里双向链表的类继承了(上一篇)单向链表的类,然后对涉及增删操作的方法进行重写

class DoubleLinkedList(SingleLinkedList):

    def add(self, item):
        """
        头部添加一个结点
        :param item:
        :return:
        """
        # 创建结点
        node = DoubleLinkedNode(item)
        # 将新结点的下一个结点指向原来的头结点,并将头结点指向新的结点(同单向链表)
        node.next, self.head = self.head, node
        # 如果原头结点不是None(此时node.next指向原来的头结点)
        if node.next:
            # 将原来的头结点的前一个结点指向新结点
            node.next.pre = node

    def append(self, item):
        """
        从尾部添加一个结点
        :param item: 将要添加的结点的值
        :return: None
        """
        # 创建新结点
        new_node = DoubleLinkedNode(item)
        if not self.head:
            self.head = new_node
        else:
            # 获取头结点
            node = self.head
            # 如果当前结点的下一个结点不为None
            while node.next:
                # 将当前结点指向下一个结点
                node = node.next
            # 将当前结点的下一个结点指向新节点,并将新结点的前置结点指向当前结点
            node.next, new_node.pre = new_node, node

    def remove(self, item):
        """
        根据值删除结点
        :param item: 要删除的结点的值
        :return: None
        """
        # 如果链表不为空
        if self.head:
            # 获取头结点
            node = self.head
            # 如果头结点即是要删除的结点
            if node.item == item:
                # 将头结点指向下一个结点
                self.head = self.head.next
                # 如果此时链表不为空
                if self.head:
                    # 将头结点的前一个结点指向None
                    self.head.pre = None
                return
            # 如果当前结点的下一个结点不为None
            while node.next:
                # 如果当前结点的下一个结点是要删除的结点
                if node.next.item == item:
                    # 如果当前结点的下下个节点不为None
                    if node.next.next:
                        # 将当前结点的下下个节点的前置结点指向当前结点
                        node.next.next.pre = node
                    # 将当前结点的下一个结点指向下下个结点
                    node.next = node.next.next
                    # 返回
                    return
                # 将当前结点指向下一个结点
                node = node.next
        # 值不在链表中
        raise ValueError('item not in DoubleLinkedList')

    def insert(self, site, item):
        """
        插入一个结点
        :param site: 要插入的位置
        :param item: 要插入的值
        :return:
        """
        if not isinstance(site, int):
            raise TypeError("site must be integers")
        # 创建新结点
        new_node = DoubleLinkedNode(item)
        # 如过要插入的位置小于等于零
        if site <= 0:
            # 从头部添加
            self.add(item)
        # 如果要插入的位置大于等于链表的长度
        elif site >= self.length():
            # 从尾部添加
            self.append(item)
        else:
            # 获取头部结点
            node = self.head
            # 找到要插入的位置的结点
            for i in range(site):
                node = node.next
            # 将新结点的前置结点和下一个结点 分别指向当前结点的前一个结点和当前结点
            # 将当前结点的前一个节点的下一个结点指向新结点 并将当前结点的前置结点指向新结点
            new_node.next, new_node.pre, node.pre.next, node.pre = node, node.pre, new_node, new_node

猜你喜欢

转载自blog.csdn.net/qq_41864652/article/details/81121431