Re-translate the Japanese version (#1871)

* Retranslate Japanese docs with GPT-5.4

* Retranslate Japanese code with GPT-5.4
This commit is contained in:
Yudong Jin
2026-03-30 07:30:15 +08:00
committed by GitHub
parent fe6443235b
commit d7b2277d2b
1444 changed files with 83312 additions and 8363 deletions
+2
View File
@@ -0,0 +1,2 @@
add_executable(my_heap_test my_heap_test.c)
add_executable(top_k top_k.c)
+152
View File
@@ -0,0 +1,152 @@
/**
* File: my_heap.c
* Created Time: 2023-01-15
* Author: Reanon (793584285@qq.com)
*/
#include "../utils/common.h"
#define MAX_SIZE 5000
/* 最大ヒープ */
typedef struct {
// size は実際の要素数を表す
int size;
// あらかじめメモリを確保した配列を使い、拡張を避ける
int data[MAX_SIZE];
} MaxHeap;
// 関数宣言
void siftDown(MaxHeap *maxHeap, int i);
void siftUp(MaxHeap *maxHeap, int i);
int parent(MaxHeap *maxHeap, int i);
/* コンストラクタ。スライスからヒープを構築する */
MaxHeap *newMaxHeap(int nums[], int size) {
// すべての要素をヒープに入れる
MaxHeap *maxHeap = (MaxHeap *)malloc(sizeof(MaxHeap));
maxHeap->size = size;
memcpy(maxHeap->data, nums, size * sizeof(int));
for (int i = parent(maxHeap, size - 1); i >= 0; i--) {
// 葉ノード以外のすべてのノードをヒープ化
siftDown(maxHeap, i);
}
return maxHeap;
}
/* デストラクタ */
void delMaxHeap(MaxHeap *maxHeap) {
// メモリを解放する
free(maxHeap);
}
/* 左子ノードのインデックスを取得 */
int left(MaxHeap *maxHeap, int i) {
return 2 * i + 1;
}
/* 右子ノードのインデックスを取得 */
int right(MaxHeap *maxHeap, int i) {
return 2 * i + 2;
}
/* 親ノードのインデックスを取得 */
int parent(MaxHeap *maxHeap, int i) {
return (i - 1) / 2; // 切り捨て
}
/* 要素を交換 */
void swap(MaxHeap *maxHeap, int i, int j) {
int temp = maxHeap->data[i];
maxHeap->data[i] = maxHeap->data[j];
maxHeap->data[j] = temp;
}
/* ヒープのサイズを取得 */
int size(MaxHeap *maxHeap) {
return maxHeap->size;
}
/* ヒープが空かどうかを判定 */
int isEmpty(MaxHeap *maxHeap) {
return maxHeap->size == 0;
}
/* ヒープ先頭要素にアクセス */
int peek(MaxHeap *maxHeap) {
return maxHeap->data[0];
}
/* 要素をヒープに追加 */
void push(MaxHeap *maxHeap, int val) {
// 通常は、これほど多くのノードを追加すべきではない
if (maxHeap->size == MAX_SIZE) {
printf("heap is full!");
return;
}
// ノードを追加
maxHeap->data[maxHeap->size] = val;
maxHeap->size++;
// 下から上へヒープ化
siftUp(maxHeap, maxHeap->size - 1);
}
/* 要素をヒープから取り出す */
int pop(MaxHeap *maxHeap) {
// 空判定の処理
if (isEmpty(maxHeap)) {
printf("heap is empty!");
return INT_MAX;
}
// 根ノードと最も右の葉ノードを交換(先頭要素と末尾要素を交換)
swap(maxHeap, 0, size(maxHeap) - 1);
// ノードを削除
int val = maxHeap->data[maxHeap->size - 1];
maxHeap->size--;
// 上から下へヒープ化
siftDown(maxHeap, 0);
// ヒープ先頭要素を返す
return val;
}
/* ノード i から始めて、上から下へヒープ化 */
void siftDown(MaxHeap *maxHeap, int i) {
while (true) {
// ノード i, l, r のうち値が最大のノードを max とする
int l = left(maxHeap, i);
int r = right(maxHeap, i);
int max = i;
if (l < size(maxHeap) && maxHeap->data[l] > maxHeap->data[max]) {
max = l;
}
if (r < size(maxHeap) && maxHeap->data[r] > maxHeap->data[max]) {
max = r;
}
// ノード i が最大、またはインデックス l, r が範囲外なら、ヒープ化は不要なので抜ける
if (max == i) {
break;
}
// 2 つのノードを交換
swap(maxHeap, i, max);
// ループで上から下へヒープ化
i = max;
}
}
/* ノード i から始めて、下から上へヒープ化 */
void siftUp(MaxHeap *maxHeap, int i) {
while (true) {
// ノード i の親ノードを取得
int p = parent(maxHeap, i);
// 「根ノードを越えた」または「ノードの修復が不要」になったらヒープ化を終了
if (p < 0 || maxHeap->data[i] <= maxHeap->data[p]) {
break;
}
// 2 つのノードを交換
swap(maxHeap, i, p);
// ループで下から上へヒープ化
i = p;
}
}
+41
View File
@@ -0,0 +1,41 @@
/**
* File: my_heap_test.c
* Created Time: 2023-01-15
* Author: Reanon (793584285@qq.com)
*/
#include "my_heap.c"
/* Driver Code */
int main() {
/* ヒープを初期化 */
// 最大ヒープを初期化
int nums[] = {9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2};
MaxHeap *maxHeap = newMaxHeap(nums, sizeof(nums) / sizeof(int));
printf("配列を入力してヒープ化した後\n");
printHeap(maxHeap->data, maxHeap->size);
/* ヒープ頂点の要素を取得 */
printf("\nヒープの先頭要素は %d\n", peek(maxHeap));
/* 要素をヒープに追加 */
push(maxHeap, 7);
printf("\n要素 7 をヒープに追加した後\n");
printHeap(maxHeap->data, maxHeap->size);
/* ヒープ頂点の要素を取り出す */
int top = pop(maxHeap);
printf("\nヒープの先頭要素 %d を取り出した後\n", top);
printHeap(maxHeap->data, maxHeap->size);
/* ヒープのサイズを取得 */
printf("\nヒープの要素数は %d\n", size(maxHeap));
/* ヒープが空かどうかを判定 */
printf("\nヒープが空かどうか %d\n", isEmpty(maxHeap));
// メモリを解放する
delMaxHeap(maxHeap);
return 0;
}
+73
View File
@@ -0,0 +1,73 @@
/**
* File: top_k.c
* Created Time: 2023-10-26
* Author: krahets (krahets163.com)
*/
#include "my_heap.c"
/* 要素をヒープに追加 */
void pushMinHeap(MaxHeap *maxHeap, int val) {
// 要素を反転する
push(maxHeap, -val);
}
/* 要素をヒープから取り出す */
int popMinHeap(MaxHeap *maxHeap) {
// 要素を反転する
return -pop(maxHeap);
}
/* ヒープ先頭要素にアクセス */
int peekMinHeap(MaxHeap *maxHeap) {
// 要素を反転する
return -peek(maxHeap);
}
/* ヒープから要素を取り出す */
int *getMinHeap(MaxHeap *maxHeap) {
// ヒープ内のすべての要素を反転して res 配列に格納
int *res = (int *)malloc(maxHeap->size * sizeof(int));
for (int i = 0; i < maxHeap->size; i++) {
res[i] = -maxHeap->data[i];
}
return res;
}
// ヒープに基づいて配列中の最大の k 個の要素を求める関数
int *topKHeap(int *nums, int sizeNums, int k) {
// 最小ヒープを初期化する
// 注意: ヒープ内の全要素を反転し、最大ヒープで最小ヒープをシミュレートする
int *empty = (int *)malloc(0);
MaxHeap *maxHeap = newMaxHeap(empty, 0);
// 配列の先頭 k 個の要素をヒープに追加
for (int i = 0; i < k; i++) {
pushMinHeap(maxHeap, nums[i]);
}
// k+1 番目の要素から開始し、ヒープ長を k に保つ
for (int i = k; i < sizeNums; i++) {
// 現在の要素がヒープ先頭より大きければ、ヒープ先頭を取り出して現在の要素を追加する
if (nums[i] > peekMinHeap(maxHeap)) {
popMinHeap(maxHeap);
pushMinHeap(maxHeap, nums[i]);
}
}
int *res = getMinHeap(maxHeap);
// メモリを解放する
delMaxHeap(maxHeap);
return res;
}
/* Driver Code */
int main() {
int nums[] = {1, 7, 6, 3, 2};
int k = 3;
int sizeNums = sizeof(nums) / sizeof(nums[0]);
int *res = topKHeap(nums, sizeNums, k);
printf("最大の %d 個の要素は: ", k);
printArray(res, k);
free(res);
return 0;
}