木の操作には木の巡回と呼ばれる探索方法があります。
その探索方法を学びます。
例として以下の2分木を定義します。
0 1 4 2 3 5 8 6 7
この2分木を例として、木の巡回の出力例を見ていきましょう。
木の先行順巡回(Preorder Tree Walk)
根節点、左部分木、右部分木の順で節点の番号を出力します。
出力例
0 1 2 3 4 5 6 7 8
木の中間順巡回(Inorder Tree Walk)
左部分木、根節点、右部分木の順で節点の番号を出力します。
出力例
2 1 3 0 6 5 7 4 8
木の後行順巡回(Postorder Tree Walk)
左部分木、右部分木、根節点の順で節点の番号を出力します。
出力例
2 3 1 6 7 5 8 4 0
では、AIDU ONLINE JUDGEのALDS1_7_Cの木巡回の問題例に、
プログラムをチェックしましょう。
// 先行順巡回 void preParse(int u){ if(u == NIL)return; printf(" %d",u); preParse(gNode[u].left); preParse(gNode[u].right); } // 中間順巡回 void inParse(int u){ if(u == NIL)return; inParse(gNode[u].left); printf(" %d",u); inParse(gNode[u].right); } // 後行順巡回 void postParse(int u){ if(u == NIL) return; postParse(gNode[u].left); postParse(gNode[u].right); printf(" %d",u); }
出力する位置を変えることによって、
各々の出力形式で出力しています。
では、全体のソースです。
#include <stdio.h> #include <iostream> using namespace std; // node最大量 #define MAX 100000 #define NIL -1 struct Node { int parent; int left; int right; }; // 配列で保持する Node gNode[MAX]; // 先行順巡回 void preParse(int u){ if(u == NIL)return; printf(" %d",u); preParse(gNode[u].left); preParse(gNode[u].right); } // 中間順巡回 void inParse(int u){ if(u == NIL)return; inParse(gNode[u].left); printf(" %d",u); inParse(gNode[u].right); } // 後行順巡回 void postParse(int u){ if(u == NIL) return; postParse(gNode[u].left); postParse(gNode[u].right); printf(" %d",u); } int main(){ int left,right,v,n,root = 0; cin >> n; // 初期化 for(int i = 0;i < n;++i){ gNode[i].parent = gNode[i].left = gNode[i].right = NIL; } for(int i = 0;i < n;++i){ cin >> v >> left >> right; gNode[v].left = left; gNode[v].right = right; // 親の設定 if(left != NIL){ gNode[left].parent = v; } if(right != NIL){ gNode[right].parent = v; } } // rootを探す for(int i = 0;i < n;++i){ if(gNode[i].parent == NIL){ root = i; } } cout << "Preorder\n"; preParse(root); cout << "\n"; cout << "Inorder\n"; inParse(root); cout << "\n"; cout << "Postorder\n"; postParse(root); cout << "\n"; return 0; }
0 件のコメント:
コメントを投稿