620 likes | 749 Views
アルゴリズムとデータ構造 補足資料 13-3 「 2 分探索木からの節点の削除」. 横浜国立大学 理工 学部 数物・電子情報系学科 富井尚志. 探索木のオペレータ. 探索木 を探索する 探索木に節点を追加(挿入)する 探索木から節点を削除する 端点(葉: leaf )の削除 一つの子孫しか持たない節点の削除 二つの子孫を持つ接点の削除. 探索木のオペレータ. 探索木 を探索する 探索木に節点を追加(挿入)する 探索木から節点を削除する 端点(葉: leaf )の削除 一つの子孫しか持たない節点の削除 二つの子孫を持つ接点の削除.
E N D
アルゴリズムとデータ構造補足資料13-3「2分探索木からの節点の削除」アルゴリズムとデータ構造補足資料13-3「2分探索木からの節点の削除」 横浜国立大学 理工学部 数物・電子情報系学科 富井尚志
探索木のオペレータ • 探索木を探索する • 探索木に節点を追加(挿入)する • 探索木から節点を削除する • 端点(葉:leaf)の削除 • 一つの子孫しか持たない節点の削除 • 二つの子孫を持つ接点の削除
探索木のオペレータ • 探索木を探索する • 探索木に節点を追加(挿入)する • 探索木から節点を削除する • 端点(葉:leaf)の削除 • 一つの子孫しか持たない節点の削除 • 二つの子孫を持つ接点の削除
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 delete(8, root) 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 NULL 7 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 NULL 7 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 NULL 7 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 NULL 7 delete(8, t->right) NULL if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 delete(8, t->right) NULL if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 NULL 1 6 10 NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 delete(8, t->right) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 2 9 NULL 1 6 10 NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 2 9 NULL 1 6 10 NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root delete(8, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 8 7 2 9 NULL 1 6 10 NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
端点(葉:leaf)の削除 main() … root = delete(8, root); ... ※ メンバ count は省略 root 7 2 9 NULL 1 6 10 NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
探索木のオペレータ • 探索木を探索する • 探索木に節点を追加(挿入)する • 探索木から節点を削除する • 端点(葉:leaf)の削除 • 一つの子孫しか持たない節点の削除 • 二つの子孫を持つ接点の削除
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 delete(6, root) 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL ゴールのイメージ 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 delete(6, root) 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 8 10 NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 delete(6, t->left) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 2 9 1 8 10 NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 2 9 1 8 10 NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root delete(6, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 6 7 2 9 1 8 10 NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
一つの子孫しか持たない節点の削除 main() … root = delete(6, root); ... ※ メンバ count は省略 root 7 2 9 1 8 10 NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
探索木のオペレータ • 探索木を探索する • 探索木に節点を追加(挿入)する • 探索木から節点を削除する • 端点(葉:leaf)の削除 • 一つの子孫しか持たない節点の削除 • 二つの子孫を持つ接点の削除
二つの子孫を持つ接点の削除 main() … root = delete(7, root); ... ※ メンバ count は省略 root 7 2 delete(7, root) 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
二つの子孫を持つ接点の削除 main() … root = delete(7, root); ... ※ メンバ count は省略 root 左部分木の 最右要素で 置き換える 6 値をコピー 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL ゴールのイメージ 4 3 5 NULL NULL NULL NULL
二つの子孫を持つ接点の削除 main() … root = delete(7, root); ... ※ メンバ count は省略 root 7 2 delete(7, root) 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
二つの子孫を持つ接点の削除 main() … root = delete(7, root); ... ※ メンバ count は省略 root delete(7, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 7 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
二つの子孫を持つ接点の削除 main() … root = delete(7, root); ... ※ メンバ count は省略 root delete(7, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 7 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
二つの子孫を持つ接点の削除 main() del(t, t->left) … root = delete(7, root); ... if ( t->right != NULL ) t->right = del( dstt, t->right ); else{ dstt->key = t->key; dstt->count = t->count; q = t; t = t->left; free(q); } return (t); t q ※ メンバ count は省略 root dstt delete(7, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 7 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
二つの子孫を持つ接点の削除 main() del(t, t->left) … root = delete(7, root); ... if ( t->right != NULL ) t->right = del( dstt, t->right ); else{ dstt->key = t->key; dstt->count = t->count; q = t; t = t->left; free(q); } return (t); t q ※ メンバ count は省略 root dstt delete(7, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 7 7 2 9 1 6 8 10 NULL NULL NULL NULL NULL NULL NULL 4 3 5 NULL NULL NULL NULL
二つの子孫を持つ接点の削除 main() del(t, t->left) … root = delete(7, root); ... if ( t->right != NULL ) t->right = del( dstt, t->right ); else{ dstt->key = t->key; dstt->count = t->count; q = t; t = t->left; free(q); } return (t); t q ※ メンバ count は省略 root dstt delete(7, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 7 7 2 9 1 6 8 10 del(t, t->left) NULL NULL NULL NULL NULL NULL NULL if ( t->right != NULL ) t->right = del( dstt, t->right ); else{ dstt->key = t->key; dstt->count = t->count; q = t; t = t->left; free(q); } return (t); t q dstt 4 3 5 NULL NULL NULL NULL
二つの子孫を持つ接点の削除 main() del(t, t->left) … root = delete(7, root); ... if ( t->right != NULL ) t->right = del( dstt, t->right ); else{ dstt->key = t->key; dstt->count = t->count; q = t; t = t->left; free(q); } return (t); t q ※ メンバ count は省略 root dstt delete(7, root) if ( t == NULL ) printf(“見つかりませんでした\n”); else if ( x < t->key ) t->left = delete( x, t->left ); else if ( x > t->key ) t->right = delete( x, t->right ); else{ if( t->right == NULL ){ q = t; t = t->left; free(q); } else if( t->left == NULL ){ q = t; t = t->right; free(q); } else { t->left = del( t, t->left ); } } return (t); x t q 7 7 値をコピー 2 9 1 6 8 10 del(t, t->left) NULL NULL NULL NULL NULL NULL NULL if ( t->right != NULL ) t->right = del( dstt, t->right ); else{ dstt->key = t->key; dstt->count = t->count; q = t; t = t->left; free(q); } return (t); t q dstt 4 3 5 NULL NULL NULL NULL