关于通过Python创建链表

链表是一种线性表数据结构

对于c++来说,构建链表是通过结构体和指针来实现的

而对于Python来说,链表是通过类来创建的

链表是由链节点通过next连接而成的,每个链节点存放一个数据元素,还存放一个后继指针,用于指出其后继元素所在链节点的地址

在Python中实现单链表,先定义一个链节点类:

class ListNode:
    def __init__(self,val = 0,next = None):  # val表示数据元素的值,next表示后继指针
        self.val = val
        self.next = next

然后定义完整的链表类:

class LinkedList:
    def __init__(self):
        self.head = None   # 链节点变量head表示链表的头节点

然后在链表类里,定义链表基本操作的实例方法:

# 1 根据data建立一个新链表
    def create(self,data):
        self.head = ListNode(0)  # 实例化对象,头节点对应的元素一般设置为0
        cur = self.head
        for i in range(len(data)):
            node = ListNode(data[i])  # 实例化对象
            cur.next = node
            cur = node

    # 2 求线性链表长度
    def length(self):
        count = 0
        cur = self.head   # 遍历链表指针,count指针指向链节点
        while cur:
            count += 1
            cur = cur.next
        return count

    # 3 在链表中查找值为val的元素
    def find(self,val):
        cur = self.head
        while cur:
            if cur.val == val:
                return cur    # 查找成功,返回被查找节点的地址
            cur = cur.next
        return None

    # 4 在链表头部插入元素(插在了头节点之前),此时头结点就变成了它
    def insertFront(self,val):
        node = ListNode(val)
        node.next = self.head
        self.head = node

    # 5 在链表尾部插入元素
    def insertRear(self,val):
        cur = self.head
        while cur.next:
            cur = cur.next
        node = ListNode(val)
        cur.next = node

    # 6 在链表中间插入元素
    def insertInside(self,index,val):  #在链表下标为index(即第index个链节点)的节点之前插入值为val的链节点
        count = 0
        cur = self.head
        while cur and count < index - 1:
            cur = cur.next
            count += 1
        if not cur:
            return 'Error'
        node = ListNode(val)
        node.next = cur.next
        cur.next = node

    # 7 将链表中下标为index(即第index个链节点,注意不包括头节点)的元素的值改为val
    def change(self,index,val):
        count = 0
        cur = self.head
        while cur and count < index:
            count += 1
            cur = cur.next
        if not cur:
            return 'Error'
        cur.val = val

    # 8 删除链表的第一个链节点
    def removeFront(self):
        if self.head:
            self.head = self.head.next

    # 9 删除链表的最后一个链节点
    def removeRear(self):
        if not self.head.next or not self.head:
            return 'Error'
        cur = self.head
        while cur.next.next:
            cur = cur.next
        cur.next = None

    # 10 删除链表下标为index的链节点
    def removeInside(self,index):
        cur = self.head
        count = 0
        while cur.next and count < index - 1:
            count += 1
            cur = cur.next
        if not cur:
            return 'Error'
        cur.next = cur.next.next

 为了方便查看链表中每个链节点所存放的数据元素,我还自定义了一个输出链表元素的实例方法:

    def disp(self):
        blist = []
        cur = self.head
        while cur:
            blist.append(cur.val)
            cur = cur.next
        print(blist)

验证代码如下: 

alist = LinkedList()
alist.create([1,2,3,4,5,6])
print(f"链表的长度为{alist.length()}")
print(f'值为4的元素的地址为{alist.find(4)}')
print('经过插入操作的链表变为:')
alist.insertFront(7)
alist.insertRear(10)
alist.insertInside(3,12)
alist.disp()
print('经过删除操作的链表变为:')
alist.removeFront()
alist.removeRear()
alist.removeInside(6)
alist.disp()

代码测试结果如下:

 

需要注意的是,我这里创建的链表是有头结点的

而下面我将以leetcode0707题为例,建立一个不带头结点的单链表,大家要注意两种链表的区别和联系

创建链节点类:

class ListNode:

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

 创建链表类:

class MyLinkedList:

    def __init__(self):
        self.size = 0   #size保存有效节点数
        self.head = ListNode(0)      #head是头结点  注意下标为0的节点是head.next 可理解为不带头结点的链表

然后在链表类里,定义链表基本操作的实例方法: 

    def get(self, index):  #获取链表中下标为 index 的节点的值
        if index < 0 or index >= self.size:
            return -1
        cur = self.head
        for i in range(index + 1):
            cur = cur.next
        return cur.val

    def addAtHead(self, val):  #将一个值为 val 的节点插入到链表中第一个元素之前
        self.addAtIndex(0, val)

    def addAtTail(self, val):  #将一个值为 val 的节点追加到链表中作为链表的最后一个元素
        self.addAtIndex(self.size, val)

    def addAtIndex(self, index, val):  #将一个值为 val的节点插入到链表中下标为 index 的节点之前
        if index > self.size:
            return
        index = max(0, index)
        self.size += 1
        pred = self.head
        for i in range(index):
            pred = pred.next
        node = ListNode(val)
        node.next = pred.next
        pred.next = node

    def deleteAtIndex(self, index):     #删除链表中下标为 index 的节点
        if index < 0 or index >= self.size:
            return
        self.size -= 1
        pred = self.head
        for i in range(index):
            pred = pred.next
        pred.next = pred.next.next

为了便于查看链表中每个链节点所存储的元素,我同样定义了链表输出方法:

    def disp(self):
        blist = []
        cur = self.head.next
        while cur:
            blist.append(cur.val)
            cur = cur.next
        print(blist)

验证代码如下:

alist = MyLinkedList()
alist.size = 6
cur = alist.head       #构造原始链表
for i in range(alist.size):
    n = int(input('请输入数据:'))
    cur.next = ListNode(n)
    cur = cur.next
print('原始链表的元素为:')
alist.disp()
alist.addAtHead(12)
alist.addAtTail(13)
alist.addAtIndex(3,7)
print('增加元素后的链表的元素为:')
alist.disp()
alist.deleteAtIndex(4)
print('删除元素后的链表的元素为:')
alist.disp()

代码测试结果如下:

 

此上就是我的心得体会,如有不足,望各位予以纠正 

 

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值