ruki il y a 2 mois
Parent
commit
1c435bde69

+ 289 - 0
docs/api/scripts/extension-modules/core/base/heap.md

@@ -0,0 +1,289 @@
+
+# heap
+
+The heap module provides priority queue data structures implemented as binary heaps. This is an extension module of xmake.
+
+::: tip TIP
+To use this module, you need to import it first: `import("core.base.heap")`
+:::
+
+## heap.valueheap
+
+- Create a value heap
+
+```lua
+import("core.base.heap")
+
+local h = heap.valueheap(options)
+```
+
+Creates a new value heap using a Lua table. The heap is a min-heap by default, but can be customized with a comparison function.
+
+Parameters in `options`:
+- `cmp` - Optional comparison function. Should return true if the first argument has higher priority than the second
+
+```lua
+-- Create a min-heap (default)
+local h = heap.valueheap()
+
+-- Create a max-heap
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a > b
+    end
+}
+
+-- Create a priority queue with custom objects
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a.priority < b.priority
+    end
+}
+```
+
+Initialize with existing values:
+
+```lua
+-- Create heap with initial values
+local h = heap.valueheap{1, 5, 3, 7, 2}
+```
+
+## heap:push
+
+- Push a value onto the heap
+
+```lua
+heap:push(value)
+```
+
+Adds a value to the heap and maintains the heap property. The value will be placed in the correct position according to the comparison function.
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+h:push(3)
+
+print(h:peek())  -- Output: 3 (smallest value)
+```
+
+Push custom objects:
+
+```lua
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a.priority < b.priority
+    end
+}
+
+h:push{priority = 20, data = 'low'}
+h:push{priority = 10, data = 'high'}
+h:push{priority = 15, data = 'medium'}
+
+print(h:peek().data)  -- Output: high (priority 10)
+```
+
+::: tip TIP
+The value cannot be nil.
+:::
+
+## heap:pop
+
+- Pop a value from the heap
+
+```lua
+local value = heap:pop(index)
+```
+
+Removes and returns a value from the heap. If no index is provided, removes the top element (highest priority). After removal, the heap property is maintained.
+
+Parameters:
+- `index` - Optional. The position to pop from (1-based). Defaults to 1 (top of heap)
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+
+local v1 = h:pop()  -- Returns 5 (smallest)
+local v2 = h:pop()  -- Returns 10
+local v3 = h:pop()  -- Returns 20
+```
+
+Pop with custom priority:
+
+```lua
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a.priority < b.priority
+    end
+}
+
+h:push{priority = 20, data = 'bar'}
+h:push{priority = 10, data = 'foo'}
+
+local item = h:pop()
+print(item.priority)  -- Output: 10
+print(item.data)      -- Output: foo
+```
+
+## heap:peek
+
+- Peek at a value without removing it
+
+```lua
+local value = heap:peek(index)
+```
+
+Returns a value from the heap without removing it. If no index is provided, returns the top element (highest priority).
+
+Parameters:
+- `index` - Optional. The position to peek at (1-based). Defaults to 1 (top of heap)
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+
+print(h:peek())  -- Output: 5 (smallest)
+print(h:peek())  -- Output: 5 (still there)
+
+local v = h:pop()
+print(h:peek())  -- Output: 10 (next smallest)
+```
+
+Check next task without processing:
+
+```lua
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a.priority < b.priority
+    end
+}
+
+h:push{priority = 10, task = 'urgent'}
+h:push{priority = 20, task = 'normal'}
+
+if h:peek().priority < 15 then
+    print("Processing urgent task")
+    local task = h:pop()
+end
+```
+
+## heap:replace
+
+- Replace a value at a given index
+
+```lua
+heap:replace(index, value)
+```
+
+Replaces the value at the specified index with a new value and rebalances the heap to maintain the heap property.
+
+Parameters:
+- `index` - Required. The position to replace (1-based)
+- `value` - Required. The new value
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+
+-- Replace the top element
+h:replace(1, 15)
+
+print(h:pop())  -- Output: 10
+print(h:pop())  -- Output: 15
+print(h:pop())  -- Output: 20
+```
+
+Update priority in a priority queue:
+
+```lua
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a.priority < b.priority
+    end
+}
+
+h:push{priority = 10, id = 1}
+h:push{priority = 20, id = 2}
+h:push{priority = 15, id = 3}
+
+-- Update priority of element at index 2
+h:replace(2, {priority = 5, id = 2})
+
+print(h:pop().id)  -- Output: 2 (now has highest priority)
+```
+
+::: tip TIP
+Use `replace` when you need to update an element's priority without removing and re-adding it, which is more efficient.
+:::
+
+## heap.length
+
+- Get the number of elements in the heap
+
+```lua
+local count = heap.length()
+```
+
+Returns the current number of elements in the heap. This is a function, not a method.
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+
+print(h.length())  -- Output: 3
+
+h:pop()
+print(h.length())  -- Output: 2
+```
+
+Check if heap is empty:
+
+```lua
+local h = heap.valueheap()
+
+if h.length() == 0 then
+    print("Heap is empty")
+end
+
+h:push(10)
+
+if h.length() > 0 then
+    print("Heap has", h.length(), "elements")
+end
+```
+
+Process all elements:
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+
+while h.length() > 0 do
+    local v = h:pop()
+    print(v)  -- Output: 5, 10, 20
+end
+```
+
+::: tip TIP
+The heap module implements a binary heap (priority queue) data structure. By default, it's a min-heap where the smallest element has the highest priority. You can customize the comparison function to create max-heaps or heaps based on custom priority criteria. Heap operations (push, pop, peek, replace) all have O(log n) time complexity.
+:::
+
+::: warning WARNING
+- Pushed values cannot be nil
+- Index is 1-based (Lua convention)
+- Calling `pop()` on an empty heap will cause an error
+- `length()` is a function, not a property, so use `h.length()` not `h.length`
+:::
+

+ 1 - 0
docs/sidebar.ts

@@ -65,6 +65,7 @@ function coreBaseModulesApiSidebar(): DefaultTheme.SidebarItem {
       { text: 'global', link: 'extension-modules/core/base/global' },
       { text: 'graph', link: 'extension-modules/core/base/graph' },
       { text: 'hashset', link: 'extension-modules/core/base/hashset' },
+      { text: 'heap', link: 'extension-modules/core/base/heap' },
       { text: 'json', link: 'extension-modules/core/base/json' },
       { text: 'list', link: 'extension-modules/core/base/list' },
       { text: 'option', link: 'extension-modules/core/base/option' },

+ 289 - 0
docs/zh/api/scripts/extension-modules/core/base/heap.md

@@ -0,0 +1,289 @@
+
+# heap
+
+heap 模块提供了使用二叉堆实现的优先队列数据结构。这是 xmake 的扩展模块。
+
+::: tip 提示
+使用此模块需要先导入:`import("core.base.heap")`
+:::
+
+## heap.valueheap
+
+- 创建值堆
+
+```lua
+import("core.base.heap")
+
+local h = heap.valueheap(options)
+```
+
+使用 Lua 表创建一个新的值堆。默认情况下堆是最小堆,但可以使用比较函数进行自定义。
+
+`options` 中的参数:
+- `cmp` - 可选的比较函数。如果第一个参数的优先级高于第二个参数,应返回 true
+
+```lua
+-- 创建最小堆(默认)
+local h = heap.valueheap()
+
+-- 创建最大堆
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a > b
+    end
+}
+
+-- 创建自定义对象的优先队列
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a.priority < b.priority
+    end
+}
+```
+
+使用现有值初始化:
+
+```lua
+-- 使用初始值创建堆
+local h = heap.valueheap{1, 5, 3, 7, 2}
+```
+
+## heap:push
+
+- 向堆中推入一个值
+
+```lua
+heap:push(value)
+```
+
+向堆中添加一个值并维护堆属性。该值将根据比较函数放置在正确的位置。
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+h:push(3)
+
+print(h:peek())  -- 输出: 3 (最小值)
+```
+
+推入自定义对象:
+
+```lua
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a.priority < b.priority
+    end
+}
+
+h:push{priority = 20, data = 'low'}
+h:push{priority = 10, data = 'high'}
+h:push{priority = 15, data = 'medium'}
+
+print(h:peek().data)  -- 输出: high (优先级 10)
+```
+
+::: tip 提示
+值不能为 nil。
+:::
+
+## heap:pop
+
+- 从堆中弹出一个值
+
+```lua
+local value = heap:pop(index)
+```
+
+从堆中移除并返回一个值。如果未提供索引,则移除顶部元素(最高优先级)。移除后,堆属性将得到维护。
+
+参数:
+- `index` - 可选。要弹出的位置(从 1 开始)。默认为 1(堆顶)
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+
+local v1 = h:pop()  -- 返回 5 (最小)
+local v2 = h:pop()  -- 返回 10
+local v3 = h:pop()  -- 返回 20
+```
+
+使用自定义优先级弹出:
+
+```lua
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a.priority < b.priority
+    end
+}
+
+h:push{priority = 20, data = 'bar'}
+h:push{priority = 10, data = 'foo'}
+
+local item = h:pop()
+print(item.priority)  -- 输出: 10
+print(item.data)      -- 输出: foo
+```
+
+## heap:peek
+
+- 查看值而不移除它
+
+```lua
+local value = heap:peek(index)
+```
+
+从堆中返回一个值而不移除它。如果未提供索引,则返回顶部元素(最高优先级)。
+
+参数:
+- `index` - 可选。要查看的位置(从 1 开始)。默认为 1(堆顶)
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+
+print(h:peek())  -- 输出: 5 (最小)
+print(h:peek())  -- 输出: 5 (仍然存在)
+
+local v = h:pop()
+print(h:peek())  -- 输出: 10 (下一个最小)
+```
+
+检查下一个任务而不处理:
+
+```lua
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a.priority < b.priority
+    end
+}
+
+h:push{priority = 10, task = 'urgent'}
+h:push{priority = 20, task = 'normal'}
+
+if h:peek().priority < 15 then
+    print("处理紧急任务")
+    local task = h:pop()
+end
+```
+
+## heap:replace
+
+- 替换给定索引处的值
+
+```lua
+heap:replace(index, value)
+```
+
+将指定索引处的值替换为新值,并重新平衡堆以维护堆属性。
+
+参数:
+- `index` - 必需。要替换的位置(从 1 开始)
+- `value` - 必需。新值
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+
+-- 替换顶部元素
+h:replace(1, 15)
+
+print(h:pop())  -- 输出: 10
+print(h:pop())  -- 输出: 15
+print(h:pop())  -- 输出: 20
+```
+
+在优先队列中更新优先级:
+
+```lua
+local h = heap.valueheap{
+    cmp = function(a, b)
+        return a.priority < b.priority
+    end
+}
+
+h:push{priority = 10, id = 1}
+h:push{priority = 20, id = 2}
+h:push{priority = 15, id = 3}
+
+-- 更新索引 2 处元素的优先级
+h:replace(2, {priority = 5, id = 2})
+
+print(h:pop().id)  -- 输出: 2 (现在具有最高优先级)
+```
+
+::: tip 提示
+当需要更新元素的优先级而不删除和重新添加它时,使用 `replace`,这样更高效。
+:::
+
+## heap.length
+
+- 获取堆中的元素数量
+
+```lua
+local count = heap.length()
+```
+
+返回堆中当前的元素数量。这是一个函数,不是方法。
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+
+print(h.length())  -- 输出: 3
+
+h:pop()
+print(h.length())  -- 输出: 2
+```
+
+检查堆是否为空:
+
+```lua
+local h = heap.valueheap()
+
+if h.length() == 0 then
+    print("堆为空")
+end
+
+h:push(10)
+
+if h.length() > 0 then
+    print("堆有", h.length(), "个元素")
+end
+```
+
+处理所有元素:
+
+```lua
+local h = heap.valueheap()
+h:push(10)
+h:push(5)
+h:push(20)
+
+while h.length() > 0 do
+    local v = h:pop()
+    print(v)  -- 输出: 5, 10, 20
+end
+```
+
+::: tip 提示
+heap 模块实现了二叉堆(优先队列)数据结构。默认情况下,它是一个最小堆,其中最小的元素具有最高优先级。您可以自定义比较函数来创建最大堆或基于自定义优先级标准的堆。堆操作(push、pop、peek、replace)都具有 O(log n) 时间复杂度。
+:::
+
+::: warning 注意
+- 推入的值不能为 nil
+- 索引从 1 开始(Lua 约定)
+- 在空堆上调用 `pop()` 会导致错误
+- `length()` 是一个函数,不是属性,所以使用 `h.length()` 而不是 `h.length`
+:::
+