线性表、单循环链表学习

背景:
在这里插入图片描述

单循环链表是一种链表结构,其中最后一个节点指向第一个节点,从而形成一个环。

实现单循环链表通常涉及节点定义、插入节点、删除节点以及遍历链表等操作。以下是如何在Python中实现单循环链表的示例。

单循环链表的实现

1. 节点类

首先,定义链表的节点类,每个节点包含数据和指向下一个节点的指针。

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
2. 单循环链表类

接下来,定义单循环链表类,包含插入、删除和遍历等方法。

class CircularLinkedList:
    def __init__(self):
        self.head = None

    def insert(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            self.head.next = self.head
        else:
            current = self.head
            while current.next != self.head:
                current = current.next
            current.next = new_node
            new_node.next = self.head

    def delete(self, key):
        if self.head is None:
            return
        
        current = self.head
        prev = None

        while True:
            if current.data == key:
                if prev:
                    prev.next = current.next
                else:
                    # Deleting the head node
                    if current.next == self.head:
                        self.head = None
                    else:
                        tail = self.head
                        while tail.next != self.head:
                            tail = tail.next
                        tail.next = current.next
                        self.head = current.next
                return
            
            prev = current
            current = current.next

            if current == self.head:
                break

    def display(self):
        if self.head is None:
            print("List is empty")
            return
        
        current = self.head
        while True:
            print(current.data, end=" -> ")
            current = current.next
            if current == self.head:
                break
        print()

# 示例使用
cll = CircularLinkedList()
cll.insert(1)
cll.insert(2)
cll.insert(3)
cll.display()  # 输出: 1 -> 2 -> 3 -> 

cll.delete(2)
cll.display()  # 输出: 1 -> 3 -> 

代码解释

  1. 节点类 (Node):

    • __init__: 初始化节点的数据和指向下一个节点的指针。
  2. 单循环链表类 (CircularLinkedList):

    • __init__: 初始化链表的头指针。
    • insert: 在链表中插入新节点。
      • 如果链表为空,插入第一个节点并使其指向自己。
      • 如果链表不为空,找到最后一个节点并将其next指针指向新节点,然后将新节点的next指针指向头节点。
    • delete: 删除包含指定数据的节点。
      • 如果链表为空,直接返回。
      • 找到要删除的节点并更新前一个节点的next指针。
      • 如果删除的是头节点,处理特殊情况,找到尾节点并更新其next指针指向新的头节点。
    • display: 遍历并打印链表中的所有节点。

总结

单循环链表是一种方便的数据结构,适用于需要循环访问数据的场景。上面的代码展示了如何在Python中实现单循环链表的基本操作,包括插入、删除和遍历。

线性表和单链表都是常见的数据结构,用于存储和管理数据元素。它们有各自的特点和应用场景。下面详细介绍它们的概念、特点、优缺点,以及适用的场景。

线性表

概念

线性表(Linear List)是具有相同数据类型的 n 个元素的有限序列。在逻辑结构上,线性表中的数据元素具有线性关系,即每个元素有且只有一个前驱和一个后继(除第一个和最后一个元素外)。

特点
  • 有序性:线性表中的元素按线性顺序排列。
  • 唯一的前驱和后继:每个元素除了第一个元素没有前驱和最后一个元素没有后继外,其余元素都有唯一的前驱和后继。
  • 长度可变:线性表的长度是可变的,可以动态增删元素。
实现方式
  1. 顺序存储结构(数组)
  2. 链式存储结构(链表)

单链表

概念

单链表(Singly Linked List)是一种链式存储结构,其中每个节点包含数据域和指向下一个节点的指针。链表中的最后一个节点的指针指向空(None),表示链表的结束。

特点
  • 动态存储:不需要预先分配存储空间,可以动态地进行内存分配。
  • 插入和删除操作高效:在已知位置进行插入和删除操作时,无需移动其他元素,只需改变指针指向。
  • 顺序访问:只能从头节点开始顺序访问各节点,无法直接随机访问。
结构
  • 节点:包含数据域(存储数据)和指针域(指向下一个节点)。
  • 头指针:指向链表的第一个节点。

比较与对比

共同点
  • 线性结构:线性表和单链表都属于线性结构,元素之间具有线性关系。
  • 基本操作:都支持插入、删除、查找、更新、遍历等基本操作。
不同点
特点线性表(顺序存储)单链表
存储方式数组链表
内存分配需预先分配连续空间动态分配
随机访问支持不支持
插入和删除效率低,需移动元素高,只需修改指针
空间利用率可能存在空间浪费高效
实现难度简单较复杂
适用场景
  • 线性表(数组)

    • 适用于元素数量固定且变化不大的场景。
    • 适用于需要频繁随机访问元素的场景。
    • 适用于存储大小一致的数据(如基本数据类型)。
  • 单链表

    • 适用于元素数量变化频繁的场景。
    • 适用于插入和删除操作较多的场景。
    • 适用于数据量较大且不确定的场景。

示例代码

顺序存储(数组实现)
class LinearList:
    def __init__(self):
        self.data = []

    def insert(self, index, element):
        if index < 0 or index > len(self.data):
            raise IndexError("Index out of bounds")
        self.data.insert(index, element)

    def delete(self, index):
        if index < 0 or index >= len(self.data):
            raise IndexError("Index out of bounds")
        return self.data.pop(index)

    def get(self, index):
        if index < 0 or index >= len(self.data):
            raise IndexError("Index out of bounds")
        return self.data[index]

    def update(self, index, element):
        if index < 0 or index >= len(self.data):
            raise IndexError("Index out of bounds")
        self.data[index] = element

    def length(self):
        return len(self.data)

    def display(self):
        print(self.data)

# 示例使用
linear_list = LinearList()
linear_list.insert(0, 1)
linear_list.insert(1, 2)
linear_list.insert(2, 3)
linear_list.display()  # 输出: [1, 2, 3]

linear_list.update(1, 5)
linear_list.display()  # 输出: [1, 5, 3]

linear_list.delete(2)
linear_list.display()  # 输出: [1, 5]

print(linear_list.get(1))  # 输出: 5
print(linear_list.length())  # 输出: 2
单链表实现
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def insert(self, index, element):
        new_node = Node(element)
        if index == 0:
            new_node.next = self.head
            self.head = new_node
            return

        current = self.head
        for _ in range(index - 1):
            if current is None:
                raise IndexError("Index out of bounds")
            current = current.next
        
        new_node.next = current.next
        current.next = new_node

    def delete(self, index):
        if self.head is None:
            raise IndexError("Index out of bounds")

        if index == 0:
            self.head = self.head.next
            return

        current = self.head
        for _ in range(index - 1):
            if current.next is None:
                raise IndexError("Index out of bounds")
            current = current.next
        
        if current.next is None:
            raise IndexError("Index out of bounds")
        
        current.next = current.next.next

    def get(self, index):
        current = self.head
        for _ in range(index):
            if current is None:
                raise IndexError("Index out of bounds")
            current = current.next
        
        if current is None:
            raise IndexError("Index out of bounds")
        
        return current.data

    def update(self, index, element):
        current = self.head
        for _ in range(index):
            if current is None:
                raise IndexError("Index out of bounds")
            current = current.next
        
        if current is None:
            raise IndexError("Index out of bounds")
        
        current.data = element

    def length(self):
        count = 0
        current = self.head
        while current:
            count += 1
            current = current.next
        return count

    def display(self):
        current = self.head
        while current:
            print(current.data, end=" -> ")
            current = current.next
        print("None")

# 示例使用
linked_list = LinkedList()
linked_list.insert(0, 1)
linked_list.insert(1, 2)
linked_list.insert(2, 3)
linked_list.display()  # 输出: 1 -> 2 -> 3 -> None

linked_list.update(1, 5)
linked_list.display()  # 输出: 1 -> 5 -> 3 -> None

linked_list.delete(2)
linked_list.display()  # 输出: 1 -> 5 -> None

print(linked_list.get(1))  # 输出: 5
print(linked_list.length())  # 输出: 2

总结

线性表和单链表各有优缺点和适用场景。选择使用哪种数据结构,取决于具体的应用需求和操作频率。在需要频繁随机访问数据的场景下,线性表(数组)更为合适;在需要频繁插入和删除操作的场景下,单链表则更为高效。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值