Files
hello-algo/zh-hant/docs/chapter_heap/exercises.md
T
krahets 22e898c9af build
2026-07-19 07:20:08 +08:00

93 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
comments: true
---
# 8.5   練習
## 8.5.1   知識鞏固
### 1.   數字 10 入堆積後怎樣調整
陣列 `[9, 7, 8, 3, 5]` 表示一個大頂堆積。現在將數字 10 入堆積。
<!-- numbered-subquestions -->
1. 先把 10 新增到陣列末尾,它的父節點值是多少?
2. 從新節點開始向上堆積化,寫出每次交換後的陣列。
3. 最終的堆積頂元素是什麼?一共交換了幾次?
??? success "參考答案"
1. 10 新增後的索引為 5,其父節點索引為
$\lfloor(5-1)/2\rfloor=2$,父節點值為 8。
2. 10 大於 8,第一次交換後為 `[9, 7, 10, 3, 5, 8]`
10 又大於父節點 9,第二次交換後為 `[10, 7, 9, 3, 5, 8]`
此時 10 已到達根節點,堆積化結束。
3. 最終堆積頂為 10,共交換 2 次。
### 2. &nbsp; 檢查小頂堆積的父子關係
陣列 `[1, 4, 3, 7, 6, 2]` 表示一棵完全二元樹。小頂堆積要求每個父節點都不大於它的孩子。
對索引 $i$,左、右孩子索引分別為 $2i+1$ 和 $2i+2$。
<!-- numbered-subquestions -->
1. 索引 2 的孩子索引和值分別是什麼?
2. 索引 2 處的節點值為 3,它與孩子節點之間是否違反小頂堆積規則?如果違反,應交換哪兩個元素?
3. 根據第 2 問的判斷:若違反規則,寫出交換後的陣列;若不違反,說明無須交換。最後檢查其餘父子關係。
??? success "參考答案"
1. 索引 2 的左孩子索引是 5、值為 2;右孩子索引是 6,但陣列長度為 6,因此右孩子不存在。
2. 父節點值 3 大於孩子值 2,違反小頂堆積規則,應交換索引 2 和索引 5 的元素。
3. 交換後得到 `[1, 4, 2, 7, 6, 3]`。逐一檢查:
`1 ≤ 4``1 ≤ 2``4 ≤ 7``4 ≤ 6``2 ≤ 3`
所有父節點都不大於自己的孩子,因此現在滿足小頂堆積規則。
### 3. &nbsp; 用小頂堆積保留最大的三個數
要從資料流 `[4, 1, 7, 3, 8]` 中保留最大的 3 個數,可以維護一個大小不超過 3 的小頂堆積。
先把前 3 個數依次放入小頂堆積。堆積滿後,每讀入一個新數:
如果它大於堆積頂,就刪除堆積頂並放入新數;否則堆積保持不變。
請寫出每次讀入數字後堆積中保留的數字和堆積頂。
只需把保留的數字寫成集合,不要求寫出它們在堆積陣列中的排列。
??? success "參考答案"
每次讀入數字後的結果如下:
| 讀入數字 | 保留的數字 | 堆積頂 |
| --- | --- | --- |
| 4 | `{4}` | 4 |
| 1 | `{1, 4}` | 1 |
| 7 | `{1, 4, 7}` | 1 |
| 3 | `{3, 4, 7}` | 3 |
| 8 | `{4, 7, 8}` | 4 |
堆積滿後,堆積頂是當前保留數字中最小的一個。只有新數字大於堆積頂時,
才用新數字替換堆積頂。最終保留的 `{4, 7, 8}` 正是最大的 3 個數。
## 8.5.2 &nbsp; 程式設計練習
### 1. &nbsp; 尋找陣列中的第 k 大元素
給定整數陣列 `nums` 和整數 $k$,其中 $1 \le k \le n$,$n$ 是陣列長度。把陣列按從大到小排列後,請返回第 $k$ 個位置上的元素。
重複元素需要分別計數。例如,`[5, 5, 2]` 的第 2 大元素仍是 5。請使用一個大小不超過 $k$ 的小頂堆積完成。
??? tip "解題提示"
1. 第 k 大元素是最大的 k 個數中最小的那個
2. 每個數先入小頂堆積,大小超過 k 時彈出最小值
3. 走訪結束時堆積中保留最大的 k 個數,堆積頂就是答案
[LeetCode](https://leetcode.cn/problems/kth-largest-element-in-an-array/){ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" } [題目解析](https://leetcode.cn/problems/kth-largest-element-in-an-array/solutions/2361969/215-shu-zu-zhong-de-di-k-ge-zui-da-yuan-d786p/){ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" }
> **說明:** 連結中的題解講解了快速排序和快速選擇,沒有使用堆積;本練習請按照正文 8.3 節使用大小不超過 k 的小頂堆積完成