我正在查看在CC150中执行此操作的代码。其方法之一如下,它通过检索左子树的尾部来实现。
public static BiNode convert(BiNode root) {
if (root == null) {
return null;
}
BiNode part1 = convert(root.node1);
BiNode part2 = convert(root.node2);
if (part1 != null) {
concat(getTail(part1), root);
}
if (part2 != null) {
concat(root, part2);
}
return part1 == null ? root : part1;
}
public static BiNode getTail(BiNode node) {
if (node == null) {
return null;
}
while (node.node2 != null) {
node = node.node2;
}
return node;
}
public static void concat(BiNode x, BiNode y) {
x.node2 = y;
y.node1 = x;
}
public class BiNode {
public BiNode node1;
public BiNode node2;
public int data;
public BiNode(int d) {
data = d;
}
}
我不明白的是作者在书中提到的时间复杂度 O(n ^ 2)。我想到的是 T(N)= 2 * T(N / 2)+ O(N / 2),O(N / 2)由获取尾部引用消耗,因为它需要遍历一个列表O(N / 2)的长度。因此,根据主定理,它应该是O(NlogN)。我做错了什么吗?谢谢!
答案 0 :(得分:1)
public static BiNode convert(BiNode root) {//worst case BST everything if (root == null) { // on left branch (node1) return null; } BiNode part1 = convert(root.node1);//Called n times BiNode part2 = convert(root.node2);//Single call at beginning if (part1 != null) { concat(getTail(part1), root);// O(n) every recursive call } // for worst case so 1 to n // SEE BELOW if (part2 != null) { concat(root, part2); } return part1 == null ? root : part1; } public static BiNode getTail(BiNode node) {//O(n) if (node == null) { return null; } while (node.node2 != null) { node = node.node2; } return node; } public static void concat(BiNode x, BiNode y) {//O(1) x.node2 = y; y.node1 = x; }
SAMPLE TREE: 4 / 3 / 2 / 1
正如您所看到的,在最坏的情况下(Big-Oh不是普通情况),BST将仅使用node1分支进行结构化。因此,递归必须运行带有'1 + 2 + ... + N'问题大小的getTail()才能完成转换。
哪个是O(n ^ 2)