Python实现单向链表(下):整合式实现增删改查操作

上一篇:Python实现单向链表(上):15种增删改查操作

之前写了一组代码,实现了一些单向链表的操作。作为小白,写的比较臃肿。又把增删改查等类似操作整合了一下,这里的代码对比上一篇中的稍微简洁了些

大体思路

和上一篇的思路一样,写两个类:

  1. Node类:用于创建结点,并将结点以(人类)能看懂的字符串形式输出,而不是显示内存地址
  2. LinkedList类:在这一类下的方法里做了改动。这个类用于将各结点连成链表,并实现对链表进行操作的一些方法
创建Node类:
class Node:
    def __init__(self, data, next=None):
        self.data = data # 数据,当前结点的元素
        self.next = None # 指针,指向下一个结点

    def __repr__(self): # 把结点表示为一个字符串
        return "NodeValue({})".format(self.data)

调用测试:

n = Node(1)
print(n) # 因为写了__repr__方法,所以输出的是Node(1),而不是内存地址
创建LinkedList类:

准备工作:初始化方法 & 打印字符串方法
想要达到的输出效果类似于:
NodeValue(1) --> NodeValue(3) --> NodeValue(4) --> END

class LinkedList:
    def __init__(self):
        self.head = None # 初始化头结点
        self.tail = None # 初始化尾结点
        self.size = 0 # 初始化链表长度

    ## 打印链表
    def __repr__(self):
        cursor = self.head
        string_repr = ""
        while cursor:
            # 以f开头,表示在字符串内支持大括号内的python表达式
            string_repr += f"{cursor} --> "
            cursor = cursor.next
        return string_repr + "END"

下面开始是实现方法的代码:

1. get(index) 传入索引,返回在该索引位置的结点

# 传入索引,返回在该索引位置的结点
    def get(self, index):
        """
        :param index: 索引,从左数从0开始,从右数从-1开始
        """
        # 将索引变为从左数开始数的正数索引
        if index >= 0:
            leftindex = index
        else:
            leftindex = index + self.size
        # 返回节点
        current = self.head
        for i in range(leftindex):
            current = current.next
        return current

2. insert(index, data) 向链表中指定位置插入结点

    def insert(self, index, data):
        # 将索引变为从左数开始数的正数索引
        if index < 0:
            # leftindex最小值为1,最大值为self.size
            leftindex = self.size + index + 1
        else:
            leftindex = index

        new_node = Node(data)

        if (index >= 0 and index > (self.size)) or (index < 0 and leftindex > self.size):  # 如果传入的索引越界,报错
            self.size -= 1
            raise Exception("Index out of range")

        elif self.size == 0:  # 如果当前是一个空链表
            self.head = new_node
            self.tail = new_node
            self.size += 1

        elif index == 0 or (index < 0 and leftindex == 1):  # 用户想要在头部插入结点
            new_node.next = self.head
            self.head = new_node
            self.size += 1

        elif index == (self.size-1) or index == -1:  # 用户想要在尾部插入结点
            print("尾部插入")
            self.tail.next = new_node
            self.tail = new_node
            self.size += 1

        else:  # 用户想要在中间插入结点
            if index >= 0:
                pre = self.get(index - 1)
                new_node.next = pre.next
                pre.next = new_node
                self.size += 1
            else:
                pre = self.get(leftindex - 1)
                new_node.next = pre.next
                pre.next = new_node
                self.size += 1

3. remove(index, data) 删除链表中指定位置的结点

    def remove(self, index):
        # 将索引变为从左数开始数的正数索引
        if index < 0:
            # 这里的leftindex最小值为0,最大值为self.size
            # 和左数正数索引一致
            leftindex = index + self.size
        else:
            leftindex = index

        if leftindex < 0 or leftindex >= self.size: # 如果传入的索引越界,报错
            raise Exception("Index out of range")

        if leftindex == 0: # 用户想要删除头部结点
            remove_node = self.head
            self.head = self.head.next

        elif leftindex == (self.size-1): # 用户想要删除尾部结点
            pre = self.get(leftindex-1)
            remove_node = pre.next
            pre.next = None
            self.tail = pre

        else: # 用户想要中间的结点
            pre = self.get(leftindex-1)
            remove_node  = pre.next
            pre.next = pre.next.next

        self.size -= 1
        return remove_node.data

4. reverse() 反转链表

    def reverse(self):
        if self.size == 0 or self.size == 1:
            return self
        else:
            current = self.head
            pre = None
            while current:
                # 储存当前结点的正序下一个结点
                next_node = current.next
                # 让当前结点的下一个结点指向前一个结点
                current.next = pre
                # 前结点后移
                pre = current
                # 当前结点后移
                current = next_node
            # 更改头结点
            self.head = pre
            self.tail = next_node
        return self

Info
Author: Shanshan Yan
Wechat: shanshan700224
Copyright: All rights reserved
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值