Python实现单链表(带头结点)

Python实现线性表的方法前面已经讲过,但是不带头结点会有一些问题,主要就是第一个结点的处理需要和其他结点区别对待:
为了操作上的方便,在单链表第一个结点之前增加一个结点,称为头结点。头结点的数据域可以不设任何信息,也可以记录表长等相关信息。头结点的指针域指向线性表的第一个元素结点。

在这里插入图片描述
不管带不带头结点,头指针始终指向链表的第一个结点,头结点是带头结点链表的第一个结点,结点内通常不存储信息
引入头结点的好处:
1)由于开始结点的位置被存放在头结点的指针域中,所以在链表的第一个位置上的操作和在表中其他位置上的操作一致,无须进行特殊处理。
2)无论链表是否为空,其头指针是指向头结点的非空指针(空表中头结点的指针域为空),因此空表和非空表的处理也就统一了。
直接上代码,其余的函数在Python实现线性表已经展示,有兴趣的可以去看看:

class linknode():#每个结点有两个数据成员,结点元素和指向下一个结点的指针
    def __init__(self,item):            #创建节点
        self.item = item
        self.next = None
class  linklist():#初始化单链表,头结点指针域为空
    def __init__(self):#初始化的头结点的内容为None,指针域也为None
        self.headnode=linknode(None)
        self.headnode.next=None



    def headcreatlist(self, item):
        nod = linknode(item)  # 新建一个结点并赋值

        nod.next = self.headnode.next  # 结点指针域指向第一个结点
        self.headnode.next= nod  # 头结点指针指向当前结点

    def tailcreatelist(self,item):
        """尾部添加元素"""
        node =linknode(item)
        cur = self.headnode
        while cur.next != None:
            cur = cur.next
        cur.next = node

    def listlength(self):
        nod = self.headnode.next  # 头结点指针域指向第一个结点
        nodnum =0
        while (nod != None):
            nodnum += 1
            nod = nod.next  # 下一个结点
        return nodnum
        # 遍历单链表

    def tralist(self):
        show = []
        nod = self.headnode.next
        while nod != None:
            show.append(nod.item)
            nod = nod.next
        return show



if __name__ == "__main__":
    ll1=linklist()
    for i in range(10):
        ll1.headcreatlist(i*10)

    len=ll1.listlength()
    print("单链表的长度为:",len)
    sh=ll1.tralist()
    print("头插法建立的链表遍历为:",ll1.tralist())

    ll2 = linklist()
    for i in range(10):
        ll2.tailcreatelist(i * 10)

    len = ll2.listlength()
    print("单链表的长度为:", len)
    sh = ll2.tralist()
    print("头插法建立的链表遍历为:", ll2.tralist())

运行结果为:

单链表的长度为: 10
头插法建立的链表遍历为: [90, 80, 70, 60, 50, 40, 30, 20, 10, 0]
单链表的长度为: 10
头插法建立的链表遍历为: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

单链表的翻转

要实现单链表的翻转,可以遍历原链表,将每个节点的指针指向其前一个节点,从而实现链表的翻转。最后需要注意更新头节点的指针,使其指向原链表的最后一个节点。

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

class linklist():
    def __init__(self):
        self.headnode = linknode(None)
        self.headnode.next = None

    # 将链表中的节点值转换为列表,方便查看结果
    def to_list(self):
        node = self.headnode.next
        result = []
        while node:
            result.append(node.item)
            node = node.next
        return result

    # 在链表头部插入节点
    def insert_at_head(self, item):
        new_node = linknode(item)
        new_node.next = self.headnode.next
        self.headnode.next = new_node

    # 单链表翻转
    def reverse(self):
        if self.headnode.next is None:
            return
        prev = None
        current = self.headnode.next
        while current:
            next_node = current.next
            current.next = prev
            prev = current
            current = next_node
        self.headnode.next = prev

# 测试
ll = linklist()
ll.insert_at_head(1)
ll.insert_at_head(2)
ll.insert_at_head(3)
print("原始链表:", ll.to_list())  # 原始链表: [3, 2, 1]
ll.reverse()
print("翻转后链表:", ll.to_list())  # 翻转后链表: [1, 2, 3]

递归法实现单链表
基本思路是将链表分成头节点和剩余部分,然后递归地翻转剩余部分,并将头节点插入翻转后的链表的尾部。

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

class linklist():
    def __init__(self):
        self.headnode = linknode(None)
        self.headnode.next = None

    # 将链表中的节点值转换为列表,方便查看结果
    def to_list(self):
        node = self.headnode.next
        result = []
        while node:
            result.append(node.item)
            node = node.next
        return result

    # 在链表头部插入节点
    def insert_at_head(self, item):
        new_node = linknode(item)
        new_node.next = self.headnode.next
        self.headnode.next = new_node

    # 递归法翻转链表
    def reverse_recursive(self, head):
        if head is None or head.next is None:
            return head
        new_head = self.reverse_recursive(head.next)  # 递归翻转剩余部分
        head.next.next = head  # 将当前节点的下一个节点指向当前节点,实现翻转
        head.next = None  # 将当前节点的指针指向None,防止形成循环
        return new_head

    # 对外接口,调用递归函数翻转链表
    def reverse(self):
        self.headnode.next = self.reverse_recursive(self.headnode.next)

# 测试
ll = linklist()
ll.insert_at_head(1)
ll.insert_at_head(2)
ll.insert_at_head(3)
print("原始链表:", ll.to_list())  # 原始链表: [3, 2, 1]
ll.reverse()
print("翻转后链表:", ll.to_list())  # 翻转后链表: [1, 2, 3]

单链表的排序

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

class linklist():
    def __init__(self):
        self.headnode = linknode(None)
        self.headnode.next = None

    # 将链表中的节点值转换为列表,方便查看结果
    def to_list(self):
        node = self.headnode.next
        result = []
        while node:
            result.append(node.item)
            node = node.next
        return result

    # 在链表头部插入节点
    def insert_at_head(self, item):
        new_node = linknode(item)
        new_node.next = self.headnode.next
        self.headnode.next = new_node

    # 单链表插入排序
    def insertion_sort(self):
        if self.headnode.next is None:
            return

        sorted_head = linknode(None)
        current = self.headnode.next
        while current:
            prev = sorted_head
            next_node = current.next
            while prev.next and prev.next.item < current.item:
                prev = prev.next
            current.next = prev.next
            prev.next = current
            current = next_node

        self.headnode.next = sorted_head.next

# 测试
ll = linklist()
ll.insert_at_head(3)
ll.insert_at_head(1)
ll.insert_at_head(2)
ll.insert_at_head(5)
ll.insert_at_head(4)
print("原始链表:", ll.to_list())  # 原始链表: [4, 5, 2, 1, 3]
ll.insertion_sort()
print("排序后链表:", ll.to_list())  # 排序后链表: [1, 2, 3, 4, 5]

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值