Week 7 (2025/5/30)¶
今週の目的
データをヒープに格納し、ヒープの基本的な操作を行う。
今週のキーワード
- リストによる完全二分木の実装
- シフトアップ、シフトダウンによるヒープ再構築
今回はヒープソートの準備として、ヒープと呼ばれるデータ構造を実装する。 ヒープとはヒープ条件を満たす完全二分木(必ず2個以下の子を持つ左詰めの木構造) をいう。 ヒープ条件とはある節の値がその子孫のどの節よりも小さいこと である。つまり、どの節も自分の親よりも値が大きいことである。
このヒープの基本操作であるinsert
(節の挿入)、delete_min
(根の削除)、build_heap
(ヒープの構成)の3つを実装する。
課題1:ヒープにデータを挿入する¶
データをヒープに挿入するinsert
メソッドとヒープを表示するshow_tree
メソッドを備えたHeap
クラスを実装せよ。insert
メソッドは、データを格納した新しい節をヒープの最後に挿入し、その後、shift_up
メソッドを用いて挿入した節を適切な位置(ヒープ条件を満たす位置)まで押し上げる。
Heap
クラスの仕様は、以下の通りである。
Heapクラス
class Heap()
データを格納するヒープのクラス
インスタンス変数
- list: データ格納用のリスト(リスト)。0番目は使わないのでダミーデータ(e.g. 0など)を格納する。
- size: ヒープのサイズ(整数)
insert(data)
データをヒープに格納するメソッド
パラメータ
- data: 格納するデータ(
Stop
インスタンス)
shift_up(num)
ヒープのnum
番目のノードをシフトアップするメソッド
パラメータ
- num: シフトアップするデータのインデックス(整数)
show_tree()
ヒープの中身を木構造で表示するメソッド
is_heap()
ヒープの中身がヒープ条件を満たしているか確認するメソッド
返り値
- ヒープ条件を満たしていれば
True
、そうでなければFalse
を返す(ブール値)
さらに、allkyotobus_stop.dat
からバス停データを読み込み、読み込んだ順にヒープにデータをinsert
し、最後にヒープを表示するよう、以下のプログラムの穴あき部分を埋めて、実行例の通りに動くことを確認せよ。なお、ヒープの各節に割り当てられる値はバス停データの経度とする。
課題2:最小値を取り出す¶
課題1で作成したHeap
クラスに、最小値を格納した根を削除して取り出すdelete_min
メソッド追加せよ。delete_min
メソッドでは、根の削除後に根に格納された値を返し、ヒープの最後尾の要素を根に移動させること。ただし、この移動によって木構造がヒープ条件を満たさなくなるため、shift_down
メソッドを用いて根を適切な位置(ヒープ条件を満たす位置)まで押し下げる。
Heap
クラスのdelete_min
メソッドおよびshift_down
メソッドの仕様は、以下の通りである。
delete_minメソッドとshift_downメソッド
delete_min()
ヒープの最小値である根を削除するメソッド
返り値
- ヒープの根に格納されたデータ(
Stop
インスタンス)
shift_down(num)
ヒープのnum
番目のノードをシフトダウンするメソッド
パラメータ
- num: シフトダウンするデータのインデックス(整数)
さらに、課題1でallkyotobus_stop.dat
のバス停データから構築したヒープを用いてdelete_min
メソッドを3回実行し、最西から3つのバス停が取得できることを確認せよ。
課題3:ヒープを作る¶
課題1で作成したHeap
クラスに、与えられたリストからヒープを構築するbuild_heap
メソッドを追加せよ。ただし、insert
メソッドを繰り返して一つずつデータを追加しヒープを構築した課題1とは違い、与えられたリストからヒープを構成すること。
Heap
クラスのbuild_heap
メソッドの仕様は、以下の通りである。
build_heapメソッド
build_heap(list)
list
を基にヒープを構築するメソッド
パラメータ
- list: ヒープに格納するデータのリスト(
Stop
インスタンスのリスト)
ヒント
リストの中央の節が、ヒープの最後尾の節の親であることに着目して、そこからshift_down
を用いて部分木をヒープに再構成する。この構成を根まで繰り返し、ボトムアップにヒープを構築するとよい。
さらに、allkyotobus_stop.dat
から読み込んだバス停データを、読み込んだ順にリストに追加した後、build_heap
メソッドでヒープを構築して、ヒープを表示するよう実装せよ。ヒープの構成が課題1と異なるがヒープ条件を満たしていることを確認せよ。