链表(未完待续)

学习资料来源:

【算法通关手册】:https://algo.itcharge.cn/

【datawhale组队学习】https://github.com/datawhalechina/team-learning

大多是对这次组队学习的学习资料的学习笔记,非原创~

【未完待续……】

链表(Linked List)基础知识

链表简介

链表定义

链表是一种线性表数据结构。它使用一组任意的存储单元(可以是连续的,也可以是不连续的),来存储一组具有相同类型的数据。是实现线性表的链式存储结构的基础。
在这里插入图片描述

如上图所示,链表:

  • 存储单元任意。
  • 物理地址随机:逻辑上相邻的数据元素在物理地址上的相邻是随机的。
  • 后继指针next:指出某个数据元素在逻辑关系上的直接后继元素所在链节点的地址。
  • 逻辑关系:数据元素之间的逻辑关系通过指针间接反映。
  • 链节点:每个数据元素占用若干存储单元的组合。
  • 链节点存放:一个数据元素的值 + 后继指针。

链表结构优缺点:

  • 优点:
    1. 节省空间:不用实现分配存储空间,需要的时候临时申请
    2. 操作效率高:插入、移动、删除
  • 缺点:
    1. 指针需要占用存储
    2. 比数组的空间开销大
  • 总的来说链表虽然空间开销大,但是不浪费!

各种链表

单列表:就是上面那种最简单的形式

双向链表(Doubly Linked List):每个链节点中有两个指针,分别指向直接后继直接前驱。

  • 目的在于方便访问任意节点的前驱节点和后继节点。

循环列表(Circular linked list):最后链节点指向头节点,形成一个环。

  • 目的在于任意节点出发都能找到任何节点。

链表基本操作

  • 增、删、改、查。——同时也都是数据结构常见操作

链表的结构定义以及常见变量命名

  • next:链节点通过next链接构成链表

  • ListNode:链节点类

  • valListNode类中用来表示数据元素的值

  • next:指针变量——用来表示后继指针

  • LinkedList:链表类

  • headLinkedList类中的唯一链节点变量,用来表示链表的头节点

  • cur:指针变量,生成链表的时候用

创建空列表时将链表头节点变量设置为空链接python中为None

"""链节点类"""
class ListNode:
    def __init__(self, val = 0, next = None):
        self.val = val
        self.next = next # 写下一个ListNode,也可以在外面写循环写self.next,,具体看1.2.2
        
"""链表类"""
class LinkedList:
    def __init__(self):
        self.head = None

建立一个线性链表

根据线性表的数据元素动态生成链节点,并依次将其连接到链表中,做法如下:

  1. 从所给线性表的第1个数据元素开始依次获取表中的数据元素。
  2. 每获取一个数据元素,就为该数据元素生成一个新节点,将新节点插入到链表的尾部。
  3. 插入完毕之后返回第1个链节点的地址。

可见时间复杂度为 O ( n ) O(n) O(n),生成一个线性列表的代码如下:

"""将data初始化为一个新列表"""
def create(self, data):
    self.head = ListNode(0) # 头节点的值为0
    cur = self.head # 指针指向头节点?
    
    for i in range(len(data)):
        node = ListNode(data[i]) # 对列表的每一个数都实例化为ListNode类
        cur.next = node # 再把新生成的node连到上一个节点的next中去
        cur = cur.next

求线性链表的长度

  • 线性链表的长度:链节点的个数
  • cur:指针变量
  • count:计数器

代码如下:

"""获取链表的长度"""
def length(self):
    count = 0 # 初始化计数器
    cur = self.head # 指针变量指向头节点
    while cur:
        # 当指针变量指向非空时
        count += 1
        cur = cur.next
    return count

查找元素

查找值为val的位置,链表只能从头节点head开始逐个节点查找

  • 查找成功返回节点地址,否则返回None

代码如下:

"""在链表中查找元素"""
"""输出节点就是输出地址?"""

def find(self, val):
    cur = self.head
    while cur:
        """同样是通过指针变量cur来判断是否进入循环"""
        if val == cul.val:
            return cur
        cur = cur.next
        
    return None

插入元素

链表中的三种插入元素操作:头部插入、尾部插入和中间插入

  • 中间插入:在第i个链节点之前插入值为val的链结点
头部插入
  • Node:先创建一个值为val的链节点Node

代码如下:

"""在链表头部插入值为val的元素"""
def insertFront(self, val):
    node = ListNode(val) # 首先新建一个链节点
    node.next = self.head
    self.head = node
尾部插入
  • 将指针变量cur从链表的头部移动到尾部的操作次数为n,故时间复杂度 O ( n ) O(n) O(n)

代码如下:

"""在链表尾部插入元素"""
def insertRear(self, val):
    node = ListNode(val)
    cur = self.head
    
    while cur.next:
        '''为了移动到最后一个节点,当cur.next为None的时候就说明已经移到的尾部'''
        cur = cur.next
    
    cur.next = node
中间插入元素

将元素连接到第i个链节点之前,也就是第i-1个链节点之后

代码如下:

"""在链表的第i个链节点之前插入值为val的元素"""
def InsertInside(self, index, val):
    count = 0
    cur = self.head
    
    while cur and count < index - 1:
        '''当指针变量没有指空,并且计数器没有到达目标索引的时候进入循环'''
        count += 1
        cur = cur.next
        
    if not cur:
        '''如果指针指空了就报错'''
        return 'Error'
    
    node = ListNode(val)
    node.next = cur.next
    cur.next = node

改变元素

将第i个元素的值改为val(有些类似1.2.5.3 中间插入元素)

"""将第i个元素的值改为val"""
def change(self, index, val):
    count = 0
    cur = self.head
    while cur and count < index - 1:
        count += 1
        cur = cur.next
        
    if not cur:
        return 'Error'
    
    cur.val = val

删除元素

三种情况:头部删除、尾部删除以及中间删除

头部删除
def removeFront(self):
    if self.head:
        '还得先判断一下头节点是否存在'
        self.head = self.head.next
尾部删除

移动到链表尾部倒数第二个元素——算法复杂度 O ( n ) O(n) O(n)

代码如下:

def removeRear(self):
    if not self.head.next:
        '如果节点少于2个则直接报错'
        return 'Error'
    
    cur = self.head
    while cur.next.next:
        '下下个节点还存在就说明还没有移动到倒数第二个节点'
        cur = cur.next
        
    cur.next = None
中间删除

删除列表中第i个元素

代码如下:

def removeInside(self, index):
    count = 0
    cur = self.head
    
    while cur.next and count < index - 1:
        count += 1
        cur = cur.next
        
    if not cur:
        return 'Error'
    
    del_node = cur.next
    cur.next = del_node.next
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值