python数据结构 —— 链表

python数据结构 —— 链表(上)

1.初识链表

(1)链表有什么用呢?

当在一个复杂的系统运行的情况下,空闲的内存空间可能散落在内存各处,而存储数组的内存空间必须是连续的。当内存无法提供如此大的连续空间时候,此时链表的优势就体现出来—>链表的各个节点可以分散存储在内存各处,它们的内存地址无须连续

(2)链表是什么?

a.一种线性数据结构
b.每个元素是一个节点对象
c.各个节点通过“引用”相连接
【引用:记录下一个节点的内存地址,通过它可以从当前节点访问到下一个节点】
linked_list

(3)一些基础概念

a.头结点:链表的首个节点;尾结点:最后一个节点,尾结点指向的是None为空
b.初见代码:

head = {
      "value":11,
      "next":{
            "value":3,
            "next":{
                  "value":23,
                  "next":{
                        "value":7,
                        "next":None
                  }
            }
      }
}
print(head['next']['next']['value'])

上图的链表相当于
linked_list_01
运行上面的代码,执行print语句相当于找head的next的next的value,最终打印输出23

2.创建链表的构造函数

  • 首先定义Node类,初始化各个节点对象
class Node:
      def __init__(self,value):
            self.value = value 
            self.next = None

这里涉及了一个关于“类”的定义,关于这个定义我是在"python面向对象"这个板块的的学习中接触到,这里只做简单理解不进行详细展开。
类是用来描述相同的属性和方法的对象的集合,定义了集合中每个对象所共有的属性和方法。在上面中看到的self是类的实例。在我理解看来实例可以是一个小人,比如说你想要它的身高为172,那你传入的外界参数172要赋给这个小人就需要self.height = height的语句将外界的参数实例化。

  • 接着,进行链表的初始化
class LinkedList:
     def __init__(self,value):
           new_node = Node(value)
           self.head = new_node 
           self.tail = new_node 
           self.length = 1

创建一个新节点(通过Node类进行创建),让头节点和尾结点都是这个新创建的结点,链表长度为1

  • 例子
my_linked_list = LinkedList(4)
print(my_linked_list.head.value)

创建长度为1,只有一个节点值为4的链表

3.打印链表

def print_list(self):
     temp = self.head 
     while temp is not None:
           print(temp.value)
           temp = temp.next 

linked_list_02
相当于是有一个名为temp名字的节点一个一个往后读取节点中的数

  • 调用
my_linked_list.print_list()

4.append —— 将一个节点附加到链表末尾

def append(self,value):
      new_node = Node(value)
      if self.head is None:
            self.head = new_node 
            self.tail = new_node 
      else:
            self.tail.next = new_node 
            self.tail = new_node 
      self.length += 1
      return True

所有新节点的创建都调用Node这个类进行调用
先看这个链表是不是空的,如果是空的,则我创建的这个新节点是这个链表中的唯一节点,直接让首节点和尾节点是这个节点即可。如果这个链表不是空的,让新节点是尾结点的下一个节点,然后这个新的节点成为尾节点,这样就完成链表的append。

my_linked_list.append(2)

上面代码将一个值为2的节点添加到链表后面

5.pop —— 删除最后一个元素,并将tail退回指向当前的第一个元素

def pop(self):
      if self.length == 0:
            return None 
      temp = self.head 
      pre = self.head 
      while(temp.next):
            pre = temp 
            temp = temp.next
      self.tail = pre 
      self.tail.next = None 
      self.length -= 1 
      if self.length == 0:
            self.head = None 
            self.tail = None 
      return temp   

首先是判断链表长度是否为0,如果不为0,则让temppre都是头节点
linked_list03
temp.next是有值的时候,执行while语句
linked_list04
linked_list05
linked_list06
linked_list07
linked_list08
一直到temp.next是空时候
linked_list09
self.tail.next = None直接让后面的结点删去,最后记得self.length-=1
看到整个代码可能会疑惑为什么有两句if self.length == 0?第一句是删除前判断链表是否长度为零,如果长度不为零可以执行后面的一系列操作。第二句是执行完一系列操作之后判断链表长度是否为零,之所以需要判断是因为需要返回删除的值(也就是temp节点的值)。

  • 完整代码示例
class Node:
     def __init__(self,value):
           self.value = value 
           self.next = None 
           
class LinkedList:
     def __init__(self,value):
           new_node = Node(value)
           self.head = new_node 
           self.tail = new_node 
           self.length = 1 
     def print_list(self):
           temp = self.head 
           while temp is not None:
                 print(temp.value)
                 temp = temp.next 
     def append(self,value):
           new_node = Node(value)
           if self.length == 0:
                 self.head = new_node
                 self.tail = new_node 
           else:
                 self.tail.next = new_node 
                 self.tail = new_node 
           self.length += 1
     def pop(self):
           if self.length == 0:
                 return None 
           temp = self.head 
           pre = self.head 
           while(temp.next):
                 pre = temp 
                 temp = temp.next
           self.tail = pre 
           self.tail.next = None 
           self.length -= 1 
           if self.length == 0:
                 self.head = None 
                 self.tail = None 
           return temp.value
           

my_linked_list = LinkedList(1)
my_linked_list.append(2)

my_linked_list.print_list()

#执行pop 
# 2 items -- Return 2 Node 
print(my_linked_list.pop())
# 1 items -- Return 1 Node 
print(my_linked_list.pop())
# 0 items -- Return None
print(my_linked_list.pop())

下面是代码运行的结果

1
2
2
1
None
  • 26
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
数据结构与算法(Python) 一、引入概念 1-01算法引入 1-02 时间复杂度与大O表示法 1-03-最坏时间复杂度与计算规则 1-04-常见时间复杂度与大小关系 1-05-代码执行时间测量模块 1-06-Python列表类型不同操作的时间效率 1-07-Python列表与字典操作的时间复杂度 1-08-数据结构引入 二、顺序表 2-01 内存、类型本质、连续存储 recv 2-02 基本顺序表与元素外围顺序表 recv 2-03 顺序表的一体式结构与分离式结构 recv 2-04 顺序表数据区替换与扩充 recv 三、栈 3-01 栈与队列的概念 3-02 栈的实现 3-03 队列与双端队列的实现 四、链表 4-01 链表的提出 4-02 单链表的ADT模型 4-03 Python中变量标识的本质 4-04 单链表及结点的定义代码 4-05 单链表的判空、长度、遍历与尾部添加结点的代码实现 4-06 单链表尾部添加和在指定位置添加 4-07 单链表查找和删除元素 4-08 单链表与顺序表的对比 4-09 单向循环链表遍历和求长度 4-10 单向循环链表添加元素 4-11 单向循环链表删除元素 4-12 单向循环链表删除元素复习及链表扩展 4-13 双向链表及添加元素 4-14 双向链表删除元素 五、排序与搜索 5-01 排序算法的稳定性 5-02 冒泡排序及实现 5-03 选择排序算法及实现 5-04 插入算法 5-05 插入排序 5-06 插入排序2 5-07 希尔排序 5-08 希尔排序实现 5-09 快速排序 5-10 快速排序实现1 (1) 5-10 快速排序实现1 5-11 快速排序实现2 5-12 归并排序 5-13 归并排序 代码执行流程 5-14 归并排序时间复杂度及排序算法复杂度对比 5-15 二分查找 5-16 二分查找时间复杂度 六、树和树的算法 6-01 树的概念 6-02 二叉树的概念 6-03 二叉树的广度优先遍历 6-04 二叉树的实现 6-05 二叉树的先序、中序、后序遍历 6-06 二叉树由遍历确定一棵树 ———————————————— 版权声明:本文为CSDN博主「dwf1354046363」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/dwf1354046363/article/details/119832814

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值