大话数据结构之链表

🎬 博客主页:楼下安同学的博客

🎥 本文由 楼下安同学 原创 🙉

🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

📆生活明朗,万物可爱,人间值得,未来可期!✨

----❤️-----❤️-----❤️-----❤️-----❤️-----❤️-----❤️-----

链表是什么?

  链表是一种在存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现。链表是由一系列的结点组成,结点可以在运行时动态生成。每个结点包含两部分:数据域与指针域。数据域存储数据元素,指针域存储下一结点的指针。

链表使用场景

  链表的存储单元不是连续的,使用指针指向下一个元素,所以链表写操作非常的快,所以在写操作非常多的场景使用链表,那些排行榜,竞价平台的底层就是使用链表优化的。

单链表

  单向链表也叫单链表,是链表中最简单的形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。

在这里插入图片描述

head 保存首地址,item 存储数据,next 指向下一结点地址。

python实现单链表

class LinkedNode:
    # 链表节点

    def __init__(self, val):
        self.val = val
        self.next = None


class SinglyLinkedList:
    """ 单链表
    is_empty: 判断链表是否为空
    insert: 头插法
    len: 长度
    delete: 删除链表头
    loop: 遍历
    reverse: 反转链表  交换赋值
    """

    def __init__(self):
        self.__head = None

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

    def insert(self, val):
        node = LinkedNode(val)
        # 判断是否存在头结点
        if self.__head:
            node.next = self.__head

        self.__head = node

    def len(self):
        cur = self.__head
        count = 0
        while cur:
            count += 1
            cur = cur.next
        return count

    def delete(self):
        cur = self.__head
        if self.__head:
            self.__head = self.__head.next
            cur.next = None
        return cur

    def loop(self):
        cur = self.__head
        while cur:
            print(cur.val)
            cur = cur.next

    def reverse(self):
        cur, prev = self.__head, None
        while cur:
            cur.next, prev, cur = prev, cur, cur.next
        self.__head = prev
 
双链表

  双向链表也指双链表,是链表的一种。它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

在这里插入图片描述

class LinkedNode:
    # 双向链表节点

    def __init__(self, item):
        self.item = item
        self.next = None
        self.prev = None


class DoubleLinkedList:
    """双向链表
    is_empty: 判断链表是否为空
    size: 返回链表大小
    search: 查询元素  0不存在
    add: 头部插入元素
    append: 尾部添加元素
    insert: 任意位置插入
    remove: 移除元素
    loop: 循环打印链表 输出list
    reverse: 反转链表
    """

    def __init__(self):
        self.__head = None

    @property
    def is_empty(self):
        return self.__head is None

    @property
    def size(self):
        cur = self.__head
        count = 0
        while cur:
            count += 1
            cur = cur.next
        return count

    def search(self, item):
        cur = self.__head
        while cur:
            if cur.item == item:
                return 1
            cur = cur.next
        return 0

    def add(self, item):
        """
        若链表为空 将node赋值给head
        链表不为空
            将node的next属性指向头结点head
            将头结点的prev属性指向 node
            将node赋值给head
        """
        node = LinkedNode(item)
        if self.is_empty:
            self.__head = node
        else:
            node.next = self.__head
            self.__head.prev = node
            self.__head = node

    def append(self, item):
        node = LinkedNode(item)
        if self.is_empty:
            self.__head = node
        else:
            cur = self.__head
            while cur.next:
                cur = cur.next
            cur.next = node
            node.prev = cur

    def insert(self, pos: int, item):
        if pos <= 0:
            self.add(item)
        elif pos > self.size - 1:
            self.append(item)
        else:
            node = LinkedNode(item)
            cur = self.__head
            count = 0

            # 移动到指定的前一位置
            while count < pos - 1:
                count += 1
                cur = cur.next
            node.prev = cur
            node.next = cur.next
            cur.next = node

    @property
    def loop(self):
        items = []
        cur = self.__head
        while cur:
            items.append(cur.item)
            cur = cur.next
        return items

    def remove(self, item):
        """ 移除元素
        判断头部是否是要移除的元素
        判断除头部外的元素
        """
        if self.is_empty:
            return 0
        else:
            cur = self.__head
            if cur.item == item:
                if cur.next:
                    self.__head = None
                else:
                    cur.next.prev = None
                    self.__head = cur.next
                return 1
        while cur:
            if cur.item == item:
                cur.prev.next = cur.prev
                break
            cur = cur.next

    def reverse(self):
        """
        当链表为非空的时候,需要执行相应反转的操作
         # 将头节点保存在current中
         # 当链表为非空的时候,需要执行相应反转的操作
        # 分别将相邻的两个节点的前驱后继关系进行反转
        # 将下一个节点保存在next_node中
        # 将下一个节点保存在next_node中
        # 尾节点的前驱应指向原本的后继
        """
        prev = None
        cur = self.__head

        while cur:
            next = cur.next  # 保存下一节点
            cur.next = prev  # 头节点反转后,成为尾节点,next指向None
            cur.prev = next  # 尾节点指向上一个
            # prev cur 向后移动
            prev = cur
            cur = next
        self.__head = prev  # 尾节点处理

小结

  数组和链表是一切数据结构的类型,我们平常使用较多的是list,但list并不是万能的,所以我们也要掌握链表,和list一样,我们也可以封装一些方法来操作链表,上面是简单的封装的几种,根据业务场景选择即可!
在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楼下安同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值