mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
1790 字
9 分钟
python算法学习之无序表与有序表
2026-01-17

一、基本概念#

无序表#

无序表(Unordered List) 是元素之间没有特定顺序关系的线性表。 无序表特点:

  1. 元素顺序任意,没有排序要求
  2. 可以包含重复元素
  3. 元素类型可以不同(在动态类型语言中)
  4. 操作关注元素本身,而非位置关系

示例:购物清单、待办事项、标签集合

无序表的实现与应用#

  1. 基于数组的无序表

    class UnorderedArrayList:
    """基于数组的无序表实现"""
    def __init__(self):
    self.items = []
    def __str__(self):
    return f"UnorderedList: {self.items}"
    def is_empty(self):
    """判断是否为空"""
    return len(self.items) == 0
    def add(self, item):
    """添加元素 - O(1)"""
    self.items.append(item)
    def remove(self, item):
    """删除指定元素 - O(n)"""
    if item in self.items:
    self.items.remove(item)
    return True
    return False
    def search(self, item):
    """查找元素 - O(n)"""
    return item in self.items
    def size(self):
    """获取大小"""
    return len(self.items)
    def append(self, item):
    """尾部追加"""
    self.items.append(item)
    def index(self, item):
    """获取元素索引 - O(n)"""
    try:
    return self.items.index(item)
    except ValueError:
    return -1
    def pop(self, pos=None):
    """弹出元素"""
    if pos is None:
    return self.items.pop()
    return self.items.pop(pos)
    def clear(self):
    """清空列表"""
    self.items.clear()

    测试无序数组表

    ul_array = UnorderedArrayList()
    ul_array.add(5)
    ul_array.add(2)
    ul_array.add(8)
    ul_array.add(5) # 允许重复
    print(ul_array) # UnorderedList: [5, 2, 8, 5]
    print("查找8:", ul_array.search(8)) # True
    print("删除5:", ul_array.remove(5)) # True(删除第一个5)
    print(ul_array) # UnorderedList: [2, 8, 5]
  2. 基于链表的无序表

    class Node:
    """链表节点"""
    def __init__(self, data):
    self.data = data
    self.next = None
    class UnorderedLinkedList:
    """基于链表的无序表实现"""
    def __init__(self):
    self.head = None
    self._size = 0
    def __str__(self):
    values = []
    current = self.head
    while current:
    values.append(str(current.data))
    current = current.next
    return " -> ".join(values) + " -> None" if values else "Empty"
    def is_empty(self):
    return self.head is None
    def add(self, item):
    """头部添加元素 - O(1)"""
    new_node = Node(item)
    new_node.next = self.head
    self.head = new_node
    self._size += 1
    def append(self, item):
    """尾部添加元素 - O(n)"""
    new_node = Node(item)
    if self.is_empty():
    self.head = new_node
    else:
    current = self.head
    while current.next:
    current = current.next
    current.next = new_node
    self._size += 1
    def remove(self, item):
    """删除指定元素 - O(n)"""
    current = self.head
    previous = None
    while current:
    if current.data == item:
    if previous:
    previous.next = current.next
    else:
    self.head = current.next
    self._size -= 1
    return True
    previous = current
    current = current.next
    return False
    def search(self, item):
    """查找元素 - O(n)"""
    current = self.head
    while current:
    if current.data == item:
    return True
    current = current.next
    return False
    def size(self):
    return self._size
    def index(self, item):
    """获取元素位置 - O(n)"""
    current = self.head
    pos = 0
    while current:
    if current.data == item:
    return pos
    current = current.next
    pos += 1
    return -1
    def pop(self, pos=None):
    """弹出元素"""
    if self.is_empty():
    raise IndexError("Pop from empty list")
    if pos == 0 or pos is None and self.head:
    # 弹出头部
    value = self.head.data
    self.head = self.head.next
    self._size -= 1
    return value
    # 找到指定位置
    current = self.head
    previous = None
    current_pos = 0
    if pos is None:
    # 弹出尾部
    while current.next:
    previous = current
    current = current.next
    else:
    while current and current_pos < pos:
    previous = current
    current = current.next
    current_pos += 1
    if current is None:
    raise IndexError("Index out of range")
    value = current.data
    previous.next = current.next
    self._size -= 1
    return value

    测试无序链表

    ul_linked = UnorderedLinkedList()
    ul_linked.add(3)
    ul_linked.add(1)
    ul_linked.add(4)
    ul_linked.append(2)
    print(ul_linked) # 4 -> 1 -> 3 -> 2 -> None
    print("查找3:", ul_linked.search(3)) # True
    print("删除1:", ul_linked.remove(1)) # True
    print(ul_linked) # 4 -> 3 -> 2 -> None

有序表#

有序表(Ordered List) 是元素按照特定顺序排列的线性表。 有序表特点:

  1. 元素按某种规则排序(升序/降序)
  2. 通常不允许重复元素(集合)或允许重复(多重集)
  3. 支持高效查找(二分查找)
  4. 插入删除需要考虑位置

示例:电话簿、成绩排名、字典索引

有序表的实现与应用#

  1. 基于数组的有序表(排序数组)

    class OrderedArrayList:
    """基于数组的有序表实现(升序)"""
    def __init__(self):
    self.items = []
    def __str__(self):
    return f"OrderedList: {self.items}"
    def is_empty(self):
    return len(self.items) == 0
    def add(self, item):
    """添加元素并保持有序 - O(n)"""
    if self.is_empty() or item >= self.items[-1]:
    # 如果为空或大于等于最后一个元素,直接追加
    self.items.append(item)
    else:
    # 找到插入位置
    pos = 0
    while pos < len(self.items) and self.items[pos] < item:
    pos += 1
    self.items.insert(pos, item)
    def remove(self, item):
    """删除元素 - O(n)"""
    index = self._binary_search(item)
    if index != -1:
    self.items.pop(index)
    return True
    return False
    def search(self, item):
    """二分查找 - O(log n)"""
    return self._binary_search(item) != -1
    def _binary_search(self, item):
    """二分查找实现"""
    left, right = 0, len(self.items) - 1
    while left <= right:
    mid = (left + right) // 2
    if self.items[mid] == item:
    return mid
    elif self.items[mid] < item:
    left = mid + 1
    else:
    right = mid - 1
    return -1
    def size(self):
    return len(self.items)
    def pop(self, pos=None):
    """弹出元素"""
    if pos is None:
    return self.items.pop()
    return self.items.pop(pos)
    def clear(self):
    self.items.clear()
    def get_range(self, start, end):
    """获取范围内的元素"""
    import bisect
    left = bisect.bisect_left(self.items, start)
    right = bisect.bisect_right(self.items, end)
    return self.items[left:right]

    测试有序数组表

    ol_array = OrderedArrayList()
    ol_array.add(5)
    ol_array.add(2)
    ol_array.add(8)
    ol_array.add(3)
    ol_array.add(5) # 允许重复
    print(ol_array) # OrderedList: [2, 3, 5, 5, 8]
    print("查找3:", ol_array.search(3)) # True
    print("查找4:", ol_array.search(4)) # False
    print("范围查询[3, 6]:", ol_array.get_range(3, 6)) # [3, 5, 5]
  2. 基于平衡二叉搜索树的有序表

    class TreeNode:
    """二叉搜索树节点"""
    def __init__(self, key):
    self.key = key
    self.left = None
    self.right = None
    self.height = 1
    class AVLTree:
    """AVL树实现的有序表(自平衡二叉搜索树)"""
    def __init__(self):
    self.root = None
    def __str__(self):
    return "AVL Tree (inorder): " + str(self.inorder_traversal())
    def height(self, node):
    """获取节点高度"""
    if not node:
    return 0
    return node.height
    def balance_factor(self, node):
    """计算平衡因子"""
    if not node:
    return 0
    return self.height(node.left) - self.height(node.right)
    def rotate_right(self, y):
    """右旋转"""
    x = y.left
    T2 = x.right
    # 执行旋转
    x.right = y
    y.left = T2
    # 更新高度
    y.height = 1 + max(self.height(y.left), self.height(y.right))
    x.height = 1 + max(self.height(x.left), self.height(x.right))
    return x
    def rotate_left(self, x):
    """左旋转"""
    y = x.right
    T2 = y.left
    # 执行旋转
    y.left = x
    x.right = T2
    # 更新高度
    x.height = 1 + max(self.height(x.left), self.height(x.right))
    y.height = 1 + max(self.height(y.left), self.height(y.right))
    return y
    def insert(self, node, key):
    """插入节点"""
    # 1. 标准BST插入
    if not node:
    return TreeNode(key)
    if key < node.key:
    node.left = self.insert(node.left, key)
    elif key > node.key:
    node.right = self.insert(node.right, key)
    else:
    return node # 重复键不插入
    # 2. 更新高度
    node.height = 1 + max(self.height(node.left), self.height(node.right))
    # 3. 获取平衡因子
    balance = self.balance_factor(node)
    # 4. 如果不平衡,有4种情况
    # 左左情况
    if balance > 1 and key < node.left.key:
    return self.rotate_right(node)
    # 右右情况
    if balance < -1 and key > node.right.key:
    return self.rotate_left(node)
    # 左右情况
    if balance > 1 and key > node.left.key:
    node.left = self.rotate_left(node.left)
    return self.rotate_right(node)
    # 右左情况
    if balance < -1 and key < node.right.key:
    node.right = self.rotate_right(node.right)
    return self.rotate_left(node)
    return node
    def add(self, key):
    """添加元素 - O(log n)"""
    self.root = self.insert(self.root, key)
    def search(self, key):
    """查找元素 - O(log n)"""
    return self._search(self.root, key)
    def _search(self, node, key):
    if not node:
    return False
    if key == node.key:
    return True
    elif key < node.key:
    return self._search(node.left, key)
    else:
    return self._search(node.right, key)
    def inorder_traversal(self):
    """中序遍历(得到有序序列)"""
    result = []
    self._inorder(self.root, result)
    return result
    def _inorder(self, node, result):
    if node:
    self._inorder(node.left, result)
    result.append(node.key)
    self._inorder(node.right, result)

测试AVL树

avl = AVLTree()
for num in [9, 5, 10, 0, 6, 11, -1, 1, 2]:
avl.add(num)
print("AVL树中序遍历:", avl.inorder_traversal()) # [-1, 0, 1, 2, 5, 6, 9, 10, 11]
print("查找6:", avl.search(6)) # True
print("查找7:", avl.search(7)) # False

对比#

  1. 核心对比 alt text

  2. 性能对比 alt text 空间复杂度对比

    数组实现:O(n),内存连续,可能有空间浪费

    链表实现:O(n),每个节点有额外指针开销

    树实现:O(n),每个节点有左右指针和高度信息

总之#

无序表思维(就像杂货店——东西随便放,找起来麻烦)#

元素平等,顺序无关 适用场景:集合、容器、不需要顺序的存储

关键点:

  1. 关注元素存在性,而非位置
  2. 插入快,查找慢
  3. 实现简单,使用灵活

有序表思维(就像图书馆——东西排好队,找起来方便)#

元素有序,位置重要 适用场景:排名、搜索、范围查询

关键点:

  1. 元素有顺序关系
  2. 查找快,插入慢
  3. 支持高效的范围操作
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

python算法学习之无序表与有序表
https://tclothes.online/posts/算法4/sf4/
作者
衣服修改
发布于
2026-01-17
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时