CodeGym /Java 课程 /Python SELF ZH /主要术语和定义

主要术语和定义

Python SELF ZH
第 51 级 , 课程 2
可用

3.1 数据操作:插入、删除、查找

插入 (Insert):

在数据结构中添加新元素的操作。插入可以发生在数据结构的开头、结尾或任意位置。

删除 (Delete):

从数据结构中删除元素的操作。删除可以根据元素的值、索引或在数据结构中的位置发生。

查找 (Search):

在数据结构中找到元素的操作。查找可以根据值或其他标准进行。

操作示例:

  • 数组: 插入和删除需要移动元素,这可能是耗时的 — O(n)
  • 链表: 如果已知节点位置,插入和删除可以在O(1)时间内完成。
  • 哈希表: 查找、插入和删除通常在平均情况下是O(1)
  • 树: 在平衡树中,查找、插入和删除操作可以在O(log n)时间内完成。

3.2 基本概念:数组、列表、栈、队列

数组

数组是一种元素相同类型的序列,可以通过索引访问。

操作复杂度:索引访问 — O(1),插入和删除 — O(n)

示例:创建数组,修改元素并输出结果


# 创建一个数字数组
arr = [1, 2, 3, 4, 5]

# 修改索引为2(第三个元素,因为索引从0开始)的元素
arr[2] = 10

# 输出修改后的数组
print(arr)  # 输出: [1, 2, 10, 4, 5]

# 在数组末尾添加新元素
arr.append(6)
print(arr)  # 输出: [1, 2, 10, 4, 5, 6]

# 根据索引删除元素
del arr[1]
print(arr)  # 输出: [1, 10, 4, 5, 6]

列表

列表是由元素组成的集合,其中每个元素包含对下一个(单链表)或对下一个和上一个(双链表)元素的引用。

操作复杂度:已知位置的插入和删除 — O(1),查找 — O(n)

示例:创建简单的单链表并遍历


# 定义链表节点结构
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

# 创建单链表
node1 = Node("101")
node2 = Node("102")
node3 = Node("103")

# 连接节点
node1.next = node2
node2.next = node3

# 设置链表头部
list_head = node1

# 遍历链表并输出数据
current = list_head
while current:
    print(current.data)
    current = current.next

# 输出:
# 101
# 102
# 103

栈 (Stack)

是一种元素集合,遵循LIFO(后进先出)原则:最后添加的最先删除。

操作复杂度:插入(push)和删除(pop) — O(1)

示例:实现和使用栈来检查括号的平衡


def is_balanced(expression):
    stack = []
    opening = "({["
    closing = ")}]"
    pairs = {")": "(", "}": "{", "]": "["}
    
    for char in expression:
        if char in opening:
            stack.append(char)
        elif char in closing:
            if not stack or stack.pop() != pairs[char]:
                return False
    
    return len(stack) == 0

# 检查不同的表达式
print(is_balanced("({[]})"))  # 输出: True
print(is_balanced("([)]"))    # 输出: False
print(is_balanced("(("))      # 输出: False

队列 (Queue)

队列是一个元素的集合,遵循FIFO(先进先出)原则:最先添加的最先删除。

操作复杂度:插入(enqueue)和删除(dequeue) — O(1)

示例:实现和使用队列来模拟任务处理


from collections import deque

class TaskQueue:
    def __init__(self):
        self.queue = deque()

    def add_task(self, task):
        self.queue.append(task)
        print(f"任务 '{task}' 已添加到队列")

    def process_task(self):
        if self.queue:
            task = self.queue.popleft()
            print(f"处理任务: '{task}'")
        else:
            print("队列为空")

    def display_queue(self):
        print("当前任务队列:", list(self.queue))

# 创建和使用任务队列
task_queue = TaskQueue()

task_queue.add_task("发送邮件")
task_queue.add_task("更新数据库")
task_queue.add_task("创建报告")

task_queue.display_queue()

task_queue.process_task()
task_queue.process_task()

task_queue.display_queue()

# 输出:
# 任务 '发送邮件' 已添加到队列
# 任务 '更新数据库' 已添加到队列
# 任务 '创建报告' 已添加到队列
# 当前任务队列: ['发送邮件', '更新数据库', '创建报告']
# 处理任务: '发送邮件'
# 处理任务: '更新数据库'
# 当前任务队列: ['创建报告']

3.3 不同数据结构类型的区别

以下是不同类型数据结构的关键区别:

数组:

  • 访问: 快速的索引访问 — O(1)
  • 改变大小: 固定大小,增加需要复制所有元素 — O(n)
  • 适用于: 随机访问元素,当数据大小是预先已知的。

链表:

  • 访问: 慢速索引访问 — O(n)
  • 改变大小: 易于更改大小,插入和删除只需O(1)
  • 适用于: 经常添加和删除元素。

栈:

  • 工作原理: LIFO
  • 操作: 仅在一端进行插入和删除 — O(1)
  • 适用于: 任务的反向顺序执行,函数调用管理。

队列:

  • 工作原理: FIFO
  • 操作: 在不同的两端进行插入和删除 — O(1)
  • 适用于: 按任务到达顺序进行管理。

3.4 不同数据结构的应用

不同数据结构在实际中的应用示例:

数组

存储固定长度的数据,例如一周中的天或一年中的月份。

示例:使用数组处理一周中的天


# 创建一个星期数组
days = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"]

# 按索引获取星期几(例如第三天)
print(days[2])  # 输出: 星期三

# 修改一天的名称
days[0] = "星期一 (一周的开始)"
print(days[0])  # 输出: 星期一 (一周的开始)

# 遍历一周中的所有天
for day in days:
    print(day)

# 输出:
# 星期一 (一周的开始)
# 星期二
# 星期三
# 星期四
# 星期五
# 星期六
# 星期天

链表

实现动态集合,其中可以从集合的中间添加和删除元素。

示例:实现和使用链表存储待办事项


class TodoItem:
    def __init__(self, task):
        self.task = task
        self.next = None

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

    def add_task(self, task):
        new_item = TodoItem(task)
        if not self.head:
            self.head = new_item
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_item

    def display_tasks(self):
        current = self.head
        if not current:
            print("待办事项列表为空")
        else:
            while current:
                print(f"- {current.task}")
                current = current.next

# 创建和使用待办事项列表
todo = TodoList()
todo.add_task("买菜")
todo.add_task("打电话给妈妈")
todo.add_task("准备演示文稿")

print("我的待办事项列表:")
todo.display_tasks()

# 输出:
# 我的待办事项列表:
# - 买菜
# - 打电话给妈妈
# - 准备演示文稿

任务的反向顺序执行,例如递归中的函数调用处理、撤销操作。

示例:使用栈反转字符串


def reverse_string(s):
    stack = []
    # 将字符串中的每个字符放入栈中
    for char in s:
        stack.append(char)
    
    reversed_s = ''
    # 从栈中取出字符,形成反转字符串
    while stack:
        reversed_s += stack.pop()
    
    return reversed_s

# 示例使用
original = "Hello, World!"
reversed_str = reverse_string(original)
print(f"原始字符串: {original}")
print(f"反转的字符串: {reversed_str}")

# 输出:
# 原始字符串: Hello, World!
# 反转的字符串: !dlroW ,olleH

队列

按顺序处理任务,例如打印机任务、客户服务队列。

示例:模拟文档打印队列


from collections import deque

class PrinterQueue:
    def __init__(self):
        self.queue = deque()

    def add_document(self, document):
        self.queue.append(document)
        print(f"文档 '{document}' 已加入打印队列")

    def print_document(self):
        if self.queue:
            document = self.queue.popleft()
            print(f"打印文档: '{document}'")
        else:
            print("打印队列为空")

    def display_queue(self):
        print("当前打印队列:", list(self.queue))

# 创建和使用打印队列
printer = PrinterQueue()
printer.add_document("报告")
printer.add_document("演示文稿")
printer.add_document("合同")
printer.display_queue()
printer.print_document()
printer.print_document()
printer.display_queue()

# 输出:
# 文档 '报告' 已加入打印队列
# 文档 '演示文稿' 已加入打印队列
# 文档 '合同' 已加入打印队列
# 当前打印队列: ['报告', '演示文稿', '合同']
# 打印文档: '报告'
# 打印文档: '演示文稿'
# 当前打印队列: ['合同']

在这个例子中,我们创建了一个简单的打印队列模拟。文件按到达顺序加入队列并打印,展示了FIFO(先进先出)原则。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION