0Pricing
C Academy · レッスン

木構造のノードと構造

ポインターでノードをモデル化します。

「木構造のノードと構造」はCoddyKit上の無料C Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C Academyコースには全4レッスンが含まれています。

二分木とは

二分木は階層構造の一種で、各ノードが値と、最大2つの子ノードへのリンクを持ちます。子ノードには左の子と右の子があります。

最上位のノードがルートです。子を持たないノードは葉と呼びます。この形状により、二分木は高速な検索、ソート、再帰的な処理に適しています。

ノードのstruct

Cでは、データと2つの自己参照ポインターを格納するstructでノードを表します。

各ポインターは別のNodeを指すか、その側に子がない場合はNULLを指します。

struct Node {
    int value;
    struct Node *left;
    struct Node *right;
};

自己参照ポインターを使う理由

ノードは、別の完全なノードを値として含むことができません。それでは無限の記憶領域が必要になるためです。代わりに、子ノードへのポインターを保持します。

ポインターのサイズは固定なので、ヒープ上の他のノードへつなげながら、struct自体のサイズを既知の値に保てます。

struct Node {
    int value;
    struct Node *left;   /* 8 bytes on 64-bit */
    struct Node *right;  /* 8 bytes on 64-bit */
};

便利なtypedef

どこでもstruct Nodeと入力するのは面倒です。typedefを使えば、単にNodeと書けます。

この時点では型がまだ完全に定義されていないため、structの内部ではタグが必要です。

typedef struct Node {
    int value;
    struct Node *left;
    struct Node *right;
} Node;

ノードを確保する

ノードはmallocで作成し、ヒープ上に置きます。値を設定し、両方の子ポインターをNULLに初期化します。

メモリを使用する前に、mallocがNULLを返していないことを必ず確認してください。

Node *create_node(int value) {
    Node *n = malloc(sizeof(Node));
    if (n == NULL) return NULL;
    n->value = value;
    n->left = NULL;
    n->right = NULL;
    return n;
}

小さな木を手作業で構築する

リンクの仕組みを理解するため、ルートと2つの子からなる3つのノードを手作業でつなぎます。

このプログラムは木を構築して値を表示します。その後、通常は解放します(後で説明します)。

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int value;
    struct Node *left;
    struct Node *right;
} Node;

Node *create_node(int v) {
    Node *n = malloc(sizeof(Node));
    n->value = v; n->left = NULL; n->right = NULL;
    return n;
}

int main(void) {
    Node *root = create_node(10);
    root->left = create_node(5);
    root->right = create_node(15);
    printf("%d %d %d\n", root->left->value, root->value, root->right->value);
    return 0;
}

孫ノードへ到達する

アロー演算子を連鎖させることで木をたどれます。root->left->rightは左の子へ移動し、続いてその右の子へ移動します。

ポインターをたどる前に、それがNULLでないことを確認してください。そうしないとプログラムがクラッシュします。

/* root
 *   \
 *    right (15)
 *        \
 *         right->right (20)
 */
if (root->right != NULL && root->right->right != NULL)
    printf("%d\n", root->right->right->value);

再帰的にノード数を数える

再帰は木に自然に適しています。ノード数を数える場合、空の部分木は0個、それ以外では現在のノードと両方の部分木のノード数を合計します。

NULLの確認が、再帰を停止するベースケースになります。

int count_nodes(Node *root) {
    if (root == NULL) return 0;
    return 1 + count_nodes(root->left)
             + count_nodes(root->right);
}

高さを測定する

木の高さは、ルートから葉までの最長経路を辺の数で測ったものです。

2つの部分木の高さの大きいほうに1を加えます。空の木の高さを-1とすることで、ノード1つの木の高さは0になります。

int height(Node *root) {
    if (root == NULL) return -1;
    int l = height(root->left);
    int r = height(root->right);
    return 1 + (l > r ? l : r);
}

葉を識別する

葉とは、子を持たないノードです。つまり、leftとrightの両方がNULLです。

この小さなヘルパーは、多くの走査やカウント処理で役立ちます。

int is_leaf(Node *n) {
    return n != NULL && n->left == NULL && n->right == NULL;
}

構造を活用する

ここでは小さな木を構築し、再帰的なヘルパーを使ってノード数と高さを報告します。

ヘルパーは固定された形状を前提としていない点に注目してください。再帰が実際のポインターをたどるため、どのような木にも対応できます。

#include <stdio.h>
#include <stdlib.h>

typedef struct Node { int value; struct Node *left, *right; } Node;

Node *nn(int v){ Node *n=malloc(sizeof(Node)); n->value=v; n->left=n->right=NULL; return n; }
int count(Node *r){ return r? 1+count(r->left)+count(r->right):0; }
int height(Node *r){ if(!r) return -1; int l=height(r->left),x=height(r->right); return 1+(l>x?l:x); }

int main(void){
    Node *root = nn(10);
    root->left = nn(5); root->right = nn(15);
    root->left->left = nn(2);
    printf("nodes=%d height=%d\n", count(root), height(root));
    return 0;
}

クイックチェック

ノード構造についての理解度を確認しましょう。

まとめ

二分木のノードは、値と2つの自己参照ポインター(left、right)を保持します。子がない場合はNULLに設定します。

ノードはmallocで確保し、手作業でリンクして、再帰的に処理します。ノード数、 高さ、葉の判定では、NULLの確認が常にベースケースになります。

よくある質問

「木構造のノードと構造」レッスンは無料ですか?

はい。「木構造のノードと構造」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C Academyコースには全4レッスンが含まれています。

「木構造のノードと構造」で何を学びますか?

ポインターでノードをモデル化します。 ブラウザで直接実行するハンズオンコードでC Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「木構造のノードと構造」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC Academyレッスンでコードを書いて実行できますか?

はい。すべてのC Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 木構造のノードと構造
  2. BSTに挿入する
  3. 走査
  4. 検索と解放
← C Academyに戻る