分析
二分木の定義を考えると、次のようになります。
各ノードには、親、L 子、および R 子があります。
L < N
R > N
P > N
これを行うこともできます:
L < N AND R > N => L < N < R => L < R
L < N AND P > N => L < N < P => L < P
R > N AND P > N => N < MIN(P,R)
N < MIN(P,R) AND L < N => L < N < MIN(P,R)
そして、それを展開してみましょうN.L = Left-child of N
:
N.L < N
N.R > N
N.P > N
N.L.L < N.L < MIN(N, N.L.R)
N.L.R > N.L > N.L.L
N.R.L < N.R < MIN(N, N.R.R)
N.R.R > N.R > N.R.L
IF N IS N.P LEFT-CHILD: N < N.P < MIN(N.P.P, N.P.R)
IF N IS N.P RIGHT-CHILD: N > N.P.R
提案された解決策
この問題は複雑に思えますが、私の解決策は、横断順序 Left-Right-Parent で値を挿入した後にマージ ソートを使用することです。これにより、マージ ソートが平均ケースと最適ケースの間の時間の複雑さを得るのに役立ちますが、小さなトリックを使用して私が上で行った比較。
最初に、次の事実を考慮して、Left-Right-Parent トラバーサルを使用してリスト内のツリー ノードを収集N.L < N < MIN(N.R, N.P)
しO(N.R) <= O(N.P)
ます.. > N.R.R > N.R > N > N.L > N.L.L > ..
。
そのトラバーサル順序でツリー ノードを収集した後、リストにはソートされたチャンクがいくつかあります。これは、次に使用するマージ ソートに役立ちます。
このソリューションは次の地域で機能します: Time = O(n log n + n)
、Space = O(n)
Javaで書かれたアルゴリズムは次のとおりです(テストされていません):
private class Node Comparable<Node>
{
public Node R;
public Node L;
public int value;
public Node (Node L, int val, Node R)
{
this.L = L;
this.value = val;
this.R = R;
}
@Override
public int compareTo(Node other)
{
return ((other != null) ? (this.value-other.value) : 0);
}
}
class Main
{
private static Node head;
private static void recursive_collect (Node n, ArrayList<Node> list)
{
if (n == null) return;
if (n.left != null) recursive_collect (n.L, list);
if (n.right != null) recursive_collect (n.R, list);
list.add(n.value);
}
public static ArrayList<Node> collect ()
{
ArrayList<Node> list = new ArrayList<Node>();
recursive_collect (head, list);
return list;
}
// sorting the tree: O(n log n + n)
public static ArrayList<Node> sortTree ()
{
// Collecting nodes: O(n)
ArrayList<Node> list = collect();
// Merge Sort: O(n log n)
Collections.sort(list);
return list;
}
// The example in the picture you provided
public static void createTestTree ()
{
Node left1 = new Node (new Node(null,-2,null), -1, new Node(null,0,null));
Node left2 = new Node (new Node(null,-1,null), 0, new Node(null,1,null));
Node right = new Node (left2, 1, new Node(null,2,null));
head = new Node (left1, 0, right);
}
// test
public static void main(String [] args)
{
createTestTree ();
ArrayList<Node> list = sortTree ();
for (Node n : list)
{
System.out.println(n.value);
}
}
}