双向链表

也是搬砖和练习, 这段代码应该是 2年前了, 也是从网上找的, 然后记录学习, 当时也没太理解, 慢慢随着时间的流逝, 也有了一些积淀, 这样再回头来看一两前的东西, 就比较好理解了. 最近又在疯狂加班, 搞BI, 数据处理最难的部分, 写了2000多sql.. 然后还不算上前端的 sql..写了整整半个月, 都麻木了, 奇怪的一点是, 每次我想放弃的时候, 灵感就来了, 真的是又爱又恨, 工作占据了 95% 的时间, 就自己额外学的时间急剧压缩, 毕竟一个人第一次真正意义上搞了个大项目, 前后端, 数据库, 所有逻辑的实现... 也是快速成长吧, 对自己.

不扯了, 回归主题, 来复习一把双链表即一个节点,有前驱和后继, .. 不想解释啥, 直接贴代码会更加直观.

实现(参照单链表)

class Node:
    """节点类"""

    def __init__(self, data=None):
        self.data = data
        self.next = None
        self.prior = None


class DoubleLinkList:
    """双向链表"""

    def __init__(self, node=None):
        """双向链表头节点"""
        self.__head = node

    @property
    def is_empty(self):
        """链表是否为空"""
        return self.__head is None

    @property
    def length(self):
        """链表长度(元素个数)"""
        current = self.__head
        count = 0
        while current is not None:
            count += 1
            current = current.next  # 游标不断往后移动
        return count

    def travel(self):
        """遍历链表"""
        current = self.__head
        while current is not None:
            print(current.data)
            current = current.next

    def add(self, item):
        """头部插入元素"""
        node = Node(item)
        # 方案: 以node先启动 (一定要有画面感,或者直接画出来)
        # 顺序a: 1. node.next -> self.__head; 2. self.__head -> node; 3. node.next.prior -> node
        # 顺序b: 1. node.next -> self.__head; 2. self.__head.prior=node; 3.self.__head=node
        if self.is_empty:
            self.__head = node
        else:
            node.next = self.__head  # 让node的nxet-> 原来self.__head的指向元素
            self.__head = node
            node.next.prior = node

    def append(self, item):
        """尾部插入元素"""
        node = Node(item)
        if self.is_empty:
            self.__head = node
        else:
            current = self.__head
            while current.next:
                current = current.next
            # 此时游标已移动到最后一个节点
            current.next = node
            node.prior = current

    def insert(self, position, item):
        """从指定位置下标去插入元素"""
        if position <= 0:
            self.add(item)
        elif position > self.length - 1:
            self.append(item)
        else:
            current = self.__head
            count = 0
            while count < position:
                count += 1
                current = current.next
            # 游标定位到postion处,顺序断链即可, 注意顺序能够找到前后元素哈
            node = Node(item)
            node.next = current
            node.prior = current.prior
            # 前后继联系
            #current.prior.next = node; current.prior = node, 代码不唯一,关键在于如何去打断节点和连接
            current.prior = node
            node.prior.next = node

    def search(self, item):
        """搜索元素并范围其位置-首次被找到"""
        current = self.__head
        while current:
            if current.data == item:
                return True
            current = current.next
        return False
    
    def remove(self, item):
        """删除元素, 首次被找到"""
        current = self.__head
        while current:
            if current.data == item:
                # 判断是否为头结点, 如果是头节点,则 self.__head -> current.next
                if current == self.__head:
                    self.__head = current.next
                    # 判断链表是否只有一个节点
                    if current.next:
                        current.next.prior = None
                else:
                    # A, B, C 删除B:   B.prior.next -> B.next; B.next.prior -> B.prior
                    current.prior.next = current.next
                    if current.next:
                        current.next.prior = current.prior 
                break   
            else:
                # 移动指针
                current = current.next
           
l = DoubleLinkList()
l.append(2)
l.add(1)
l.append(4)
l.travel()
1
2
4
# l.add('99')
l.insert(3,'一波带走')
l.travel()
1
2
4
一波带走
l.remove(4)
l.travel()
1
2
哈哈哈
posted @ 2020-06-20 22:03  致于数据科学家的小陈  阅读(137)  评论(0编辑  收藏  举报