分析
鉴于您对二叉树的定义,我们有以下内容,
每个节点都有一个 Parent、L-child 和 R-child .. 其中:
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);
}
}
}