蓝桥杯Python赛道备赛——Day4:数据结构基础(链表、栈、队列、二叉树、堆、哈希表)

   本博客就蓝桥杯中所需的数据结构基础知识进行解释,包括:链表、栈、队列、二叉树、堆和哈希表。每一种数据结构都在给出概念解释的同时,给出了其定义方式和基本操作的示例代码,以供低年级师弟师妹们学习和练习。

   前序知识:
(1)Python基础语法
(2)Python OOP(面向对象编程)


一、链表

1. 定义:
   链表是由节点构成的线性数据结构,每个节点包含数据域(Data)和指针域(Next)。如下图所示为典型的“单链表”,节点通过指针连接形成链式结构,支持动态内存分配。
在这里插入图片描述

2. 核心知识点:
(1)节点结构:数据域存储值,指针域存储下一个节点的地址。
(2)单链表 vs 双链表:双链表多一个指向前驱节点的指针。下图为“ 双链表”,比较二者的差异:
在这里插入图片描述

(3)操作时间复杂度:
         - 访问:O(n) ;
         - 插入/删除:O(1)(已知位置时)。
(4)虚拟头节点:简化边界条件处理。
(5)优点:数组需要连续空间存储,而链表则可以是非连续空间存储,使用Next指针连接下一个节点,提升了存储资源利用率。

3. 示例代码:

# 链表
class Node:
    def __init__(self, data):
        self.data = data  # 节点数据
        self.next = None   # 下一个节点指针

# 创建链表
head = Node(1)            # 头节点
second = Node(2)
third = Node(3)
head.next = second        # 连接节点
second.next = third

# 遍历链表
def print_list(node):
    while node is not None:
        print(node.data, end=" -> ")
        node = node.next
    print("None")
print_list(head)  # 输出:1 -> 2 -> 3 -> None

# 插入节点(在第二个位置插入0)
new_node = Node(0)
new_node.next = second.next
second.next = new_node
print_list(head)  # 输出:1 -> 2 -> 0 -> 3 -> None

# 删除节点(删除值为2的节点)
current = head
while current.next.data != 2:
    current = current.next
current.next = current.next.next
print_list(head)  # 输出:1 -> 0 -> 3 -> None

二、栈

1. 定义:
   后进先出(LIFO)的线性数据结构,只允许在栈顶进行插入(push)和删除(pop)操作。
在这里插入图片描述

2. 核心知识点:
(1)核心操作:
         - push:元素入栈;
         - pop:栈顶元素出栈;
         - peek:查看栈顶元素。
(2)实现方式:数组/链表。
(3)经典应用:
         - 函数调用栈;
         - 括号匹配校验。

3. 示例代码:

# 用列表模拟栈,也可以用链表来模拟栈
stack = []
# 入栈操作
stack.append(10)  # 栈底 -> [10]
stack.append(20)  # 栈变为 [10, 20]
stack.append(30)  # 栈顶 -> [10, 20, 30]

# 查看栈顶(不弹出)
print("栈顶元素:", stack[-1])  # 输出30

# 出栈操作
top = stack.pop()  # 弹出30,栈变为 [10, 20]
print(f"弹出元素: {top}")

# 判断栈是否为空
is_empty = len(stack) == 0  # 当前栈不为空,返回False

三、队列

1. 定义:
   先进先出(FIFO)的线性数据结构,元素从队尾入队(enqueue),从队首出队(dequeue)。
在这里插入图片描述

2. 核心知识点:
(1)核心操作:
         - enqueue:元素加入队尾;
         - dequeue:移除队首元素。
(2)循环队列:解决假溢出问题。
(3)优先队列:元素带有优先级。

3. 示例代码:

# 队列
# 定义队列节点类
class QueueNode:
    def __init__(self, value):
        self.value = value    # 节点存储的值
        self.next = None      # 指向下一个节点的指针

# 手动实现队列类
class MyQueue:
    def __init__(self):
        self.head = None      # 队首指针(链表头)
        self.tail = None      # 队尾指针(链表尾)
        self.size = 0         # 队列长度

    def enqueue(self, value):
        """ 入队操作:在队尾添加元素 """
        new_node = QueueNode(value)  # 创建新节点
        if self.tail is None:        # 如果队列为空
            self.head = new_node     # 队首和队尾都指向新节点
            self.tail = new_node
        else:
            self.tail.next = new_node  # 当前队尾节点的next指向新节点
            self.tail = new_node      # 更新队尾指针
        self.size += 1

    def dequeue(self):
        """ 出队操作:移除并返回队首元素 """
        if self.is_empty():
            raise IndexError("队列为空,无法出队")  # 处理空队列异常
        value = self.head.value       # 保存队首值
        self.head = self.head.next    # 队首指针后移
        if self.head is None:         # 如果队列已空
            self.tail = None          # 同时清空队尾指针
        self.size -= 1
        return value

    def peek(self):
        """ 查看队首元素(不删除) """
        if self.is_empty():
            return None
        return self.head.value

    def is_empty(self):
        """ 判断队列是否为空 """
        return self.size == 0

# 测试队列操作
q = MyQueue()
# 入队测试
q.enqueue("A")  # 队列:A
q.enqueue("B")  # 队列:A -> B
q.enqueue("C")  # 队列:A -> B -> C
print("当前队首:", q.peek())  # 输出 A

# 出队测试
print("出队元素:", q.dequeue())  # 移除A,队列变为 B -> C
print("新队首:", q.peek())       # 输出 B

# 空队列测试
q.dequeue()  # 移除B
q.dequeue()  # 移除C
print("队列是否为空:", q.is_empty())  # 输出 True

四、二叉树

1. 定义:
   “二叉”也就是只有两个枝丫,每个节点最多有两个子节点的树形结构,包含根节点、左子树和右子树。如下图,左侧是一般的“树”结构,右侧是“二叉树”。
在这里插入图片描述

2. 核心知识点:
(1)遍历方式:
         - 前序:根->左->右;
         - 中序:左->根->右(BST有序遍历);
         - 后序:左->右->根。
(2)二叉树类型:
         - 完全二叉树,满足:
            ①除最后一层外,其他层的节点数必须达到最大值(即每层都被填满);
            ②最后一层的节点必须从左到右连续填充,不能有空隙。

在这里插入图片描述

         - 二叉搜索树(BST),是一种具有排序性质的二叉树,满足:
            ①左子树所有节点的值 < 根节点的值;
            ②右子树所有节点的值 > 根节点的值;
            ③左右子树也必须是二叉搜索树。

在这里插入图片描述

3. 示例代码:

# 二叉树
class TreeNode:
    def __init__(self, val=0):
        self.val = val      # 节点值
        self.left = None    # 左子节点
        self.right = None   # 右子节点

# 构建二叉树
#       1
#      / \
#     2   3
#    /
#   4
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)

# 中序遍历函数
def inorder_traversal(node):
    if node:  # 节点存在时递归
        inorder_traversal(node.left)   # 先遍历左子树
        print(node.val, end=" ")       # 访问当前节点
        inorder_traversal(node.right)  # 最后遍历右子树

inorder_traversal(root)  # 输出:4 2 1 3

五、堆

1. 定义:
   完全二叉树实现的优先队列,满足父节点值总大于/小于子节点值(大根堆/小根堆)。
在这里插入图片描述

2. 核心知识点:
(1)堆性质:
         - 小根堆:父节点 ≤ 子节点;
         - 大根堆:父节点 ≥ 子节点。
(2)堆化(Heapify):调整树结构维持堆特性。
(3)典型应用:Top K问题,堆排序。

3. 示例代码:

# 堆
import heapq  # Python内置堆模块(默认最小堆)

# 创建堆
heap = []
heapq.heappush(heap, 5)  # 堆结构:5
heapq.heappush(heap, 2)  # 堆结构:2-5
heapq.heappush(heap, 8)  # 堆结构:2-5-8

# 查看堆顶元素
print("堆顶元素:", heap[0])  # 输出2

# 弹出最小元素
min_val = heapq.heappop(heap)  # 弹出2,堆变为 [5,8]
print(f"弹出最小值: {min_val}")

# 列表转堆(原地转换)
nums = [9, 3, 7, 1]
heapq.heapify(nums)  # 堆结构变为 [1,3,7,9]

六、哈希表

1. 定义:
   通过哈希函数将键映射到存储位置的键值对数据结构,支持快速查找。
在这里插入图片描述

2. 核心知识点:
(1)哈希函数:均匀分布减少冲突。
(2)冲突解决:
         - 开放寻址法;
         - 链地址法(常用)。
(3)时间复杂度:平均O(1)查找。

3. 示例代码:

# 哈希表
# 使用字典实现
student_scores = {}
student_scores["Alice"] = 95  # 插入键值对
student_scores["Bob"] = 88

# 查询操作
print("Alice的成绩:", student_scores.get("Alice", -1))  # 输出95

# 处理冲突的哈希表实现
class MyHashTable:
    def __init__(self, size=10):
        self.size = size
        self.buckets = [[] for _ in range(size)]  # 创建空桶数组
    
    def _hash(self, key):
        return hash(key) % self.size  # 简单哈希函数
    
    def insert(self, key, value):
        index = self._hash(key)
        bucket = self.buckets[index]
        for i, (k, v) in enumerate(bucket):  # 遍历桶内元素
            if k == key:  # 键已存在则更新值
                bucket[i] = (key, value)
                return
        bucket.append((key, value))  # 添加新键值对
    
    def get(self, key):
        index = self._hash(key)
        bucket = self.buckets[index]
        for k, v in bucket:
            if k == key:
                return v
        return None  # 未找到返回None

# 测试自定义哈希表
ht = MyHashTable()
ht.insert("apple", 5)
ht.insert("banana", 7)
print("apple数量:", ht.get("apple"))  # 输出5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值