1 / 62

アルゴリズムとデータ構造 補足資料 13-3 「 2 分探索木からの節点の削除」

アルゴリズムとデータ構造 補足資料 13-3 「 2 分探索木からの節点の削除」. 横浜国立大学 理工 学部 数物・電子情報系学科 富井尚志. 探索木のオペレータ. 探索木 を探索する 探索木に節点を追加(挿入)する 探索木から節点を削除する 端点(葉: leaf )の削除 一つの子孫しか持たない節点の削除 二つの子孫を持つ接点の削除. 探索木のオペレータ. 探索木 を探索する 探索木に節点を追加(挿入)する 探索木から節点を削除する 端点(葉: leaf )の削除 一つの子孫しか持たない節点の削除 二つの子孫を持つ接点の削除.

moira
Download Presentation

アルゴリズムとデータ構造 補足資料 13-3 「 2 分探索木からの節点の削除」

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. アルゴリズムとデータ構造補足資料13-3「2分探索木からの節点の削除」アルゴリズムとデータ構造補足資料13-3「2分探索木からの節点の削除」 横浜国立大学 理工学部 数物・電子情報系学科 富井尚志

  2. 探索木のオペレータ • 探索木を探索する • 探索木に節点を追加(挿入)する • 探索木から節点を削除する • 端点(葉:leaf)の削除 • 一つの子孫しか持たない節点の削除 • 二つの子孫を持つ接点の削除

  3. 探索木のオペレータ • 探索木を探索する • 探索木に節点を追加(挿入)する • 探索木から節点を削除する • 端点(葉:leaf)の削除 • 一つの子孫しか持たない節点の削除 • 二つの子孫を持つ接点の削除

  4. 端点(葉: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

  5. 端点(葉: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

  6. 端点(葉: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

  7. 端点(葉: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

  8. 端点(葉: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

  9. 端点(葉: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

  10. 端点(葉: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

  11. 端点(葉: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

  12. 端点(葉: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

  13. 端点(葉: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

  14. 端点(葉: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

  15. 端点(葉: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

  16. 端点(葉: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

  17. 端点(葉: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

  18. 端点(葉: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

  19. 端点(葉: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

  20. 端点(葉: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

  21. 探索木のオペレータ • 探索木を探索する • 探索木に節点を追加(挿入)する • 探索木から節点を削除する • 端点(葉:leaf)の削除 • 一つの子孫しか持たない節点の削除 • 二つの子孫を持つ接点の削除

  22. 一つの子孫しか持たない節点の削除 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

  23. 一つの子孫しか持たない節点の削除 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

  24. 一つの子孫しか持たない節点の削除 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

  25. 一つの子孫しか持たない節点の削除 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

  26. 一つの子孫しか持たない節点の削除 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

  27. 一つの子孫しか持たない節点の削除 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

  28. 一つの子孫しか持たない節点の削除 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

  29. 一つの子孫しか持たない節点の削除 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

  30. 一つの子孫しか持たない節点の削除 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

  31. 一つの子孫しか持たない節点の削除 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

  32. 一つの子孫しか持たない節点の削除 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

  33. 一つの子孫しか持たない節点の削除 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

  34. 一つの子孫しか持たない節点の削除 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

  35. 一つの子孫しか持たない節点の削除 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

  36. 一つの子孫しか持たない節点の削除 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

  37. 一つの子孫しか持たない節点の削除 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

  38. 一つの子孫しか持たない節点の削除 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

  39. 一つの子孫しか持たない節点の削除 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

  40. 一つの子孫しか持たない節点の削除 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

  41. 探索木のオペレータ • 探索木を探索する • 探索木に節点を追加(挿入)する • 探索木から節点を削除する • 端点(葉:leaf)の削除 • 一つの子孫しか持たない節点の削除 • 二つの子孫を持つ接点の削除

  42. 二つの子孫を持つ接点の削除 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

  43. 二つの子孫を持つ接点の削除 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

  44. 二つの子孫を持つ接点の削除 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

  45. 二つの子孫を持つ接点の削除 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

  46. 二つの子孫を持つ接点の削除 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

  47. 二つの子孫を持つ接点の削除 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

  48. 二つの子孫を持つ接点の削除 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

  49. 二つの子孫を持つ接点の削除 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

  50. 二つの子孫を持つ接点の削除 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

More Related