如何在Python中使用跳表算法进行查找

2023-04-16 00:00:00 算法 查找 如何在

跳表是一种基于链表实现的数据结构,它可以在 O(log n) 的时间复杂度内进行查找、插入和删除操作,比较适合用于高效地处理大量元素的有序序列。下面是Python实现跳表算法的一个简单例子:

import random
import math

class SkipNode:
    def __init__(self, key=None, value=None):
        self.key = key
        self.value = value
        self.forward = []

class SkipList:
    def __init__(self, probability=0.5, max_level=32):
        self.head = SkipNode()
        self.probability = probability
        self.max_level = max_level

        self.head.forward = [None] * self.max_level

    def random_level(self):
        level = 1
        while random.random() < self.probability and level < self.max_level:
            level += 1
        return level

    def insert(self, key, value):
        update = [None] * self.max_level
        node = self.head

        for i in range(len(node.forward)-1, -1, -1):
            while node.forward[i] and node.forward[i].key < key:
                node = node.forward[i]

            update[i] = node

        node = node.forward[0]

        if node and node.key == key:
            node.value = value
        else:
            level = self.random_level()

            if level > len(self.head.forward):
                for i in range(len(self.head.forward), level):
                    update[i] = self.head
                    self.head.forward.append(None)

            node = SkipNode(key, value)

            for i in range(level):
                node.forward.append(None)

            for i in range(level):
                node.forward[i] = update[i].forward[i]
                update[i].forward[i] = node

    def search(self, key):
        node = self.head

        for i in range(len(node.forward)-1, -1, -1):
            while node.forward[i] and node.forward[i].key < key:
                node = node.forward[i]

        node = node.forward[0]

        if node and node.key == key:
            return node.value

        return None

    def delete(self, key):
        update = [None] * self.max_level
        node = self.head

        for i in range(len(node.forward)-1, -1, -1):
            while node.forward[i] and node.forward[i].key < key:
                node = node.forward[i]

            update[i] = node

        node = node.forward[0]

        if node and node.key == key:
            for i in range(len(node.forward)):
                update[i].forward[i] = node.forward[i]

            while len(self.head.forward) > 1 and not self.head.forward[-1]:
                self.head.forward.pop()

    def __repr__(self):
        nodes = []
        node = self.head.forward[0]

        while node:
            nodes.append((str(node.key), str(node.value)))
            node = node.forward[0]

        return str(nodes)

# Test it

list = SkipList()
keys = [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
values = ["three", "six", "nine", "twelve", "fifteen", "eighteen", "twenty-one", "twenty-four", "twenty-seven", "thirty"]

for i in range(len(keys)):
    list.insert(keys[i], values[i])

print(list.search(15))
list.delete(15)
print(list.search(15))
print(list)

在以上代码中,我们使用了两个类来实现跳表:SkipNodeSkipListSkipNode 表示跳表的节点,包含了键值对和若干个前置节点的列表。SkipList 则包含了跳表的头结点、概率和最大层数等属性,以及对应的插入、查找和删除操作。其中,random_level 方法用于生成随机层数,insert 方法用于向跳表中插入键值对,search 方法用于查找指定的键值对,delete 方法用于删除指定的键值对,__repr__ 方法用于把跳表转化为字符串输出。

测试步骤如下:

  1. 创建一个空的跳表 list

  2. 创建两个列表 keysvalues,分别包含了十个键值对。

  3. 遍历 keysvalues 列表中的元素,依次插入到跳表 list 中。

  4. 调用 list.search(15) 查找键为 15 的值,返回 “fifteen”。

  5. 调用 list.delete(15) 删除键为 15 的值。

  6. 再次调用 list.search(15) 查找键为 15 的值,返回 None

  7. 最后,把跳表 list 转化为字符串输出,得到一个包含了九个键值对的列表。

相关文章