Algorithm BST到双链接列表算法的复杂性?

Algorithm BST到双链接列表算法的复杂性?,algorithm,binary-search-tree,Algorithm,Binary Search Tree,我正在查看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) {

我正在查看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;
    }
}
我不明白的是作者在书中给出的时间复杂性。我想到的是T(N)=2*T(N/2)+O(N/2),O(N/2)被get tail引用消耗,因为它需要遍历O(N/2)的列表长度。所以根据主定理,它应该是O(NlogN)。我做错什么了吗?谢谢大家!

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; } 公共静态BiNode转换(BiNode根){//最坏情况下BST所有 如果(root==null){//在左分支(node1)上 返回null; } BiNode part1=convert(root.node1);//调用n次 BiNode part2=convert(root.node2);//开始时的单个调用 如果(第1部分!=null){ concat(getTail(part1),root);//O(n)每个递归调用 }//对于最坏情况,so 1到n //见下文 如果(part2!=null){ 海螺(根,第2部分); } 返回part1==null?根:part1; } 公共静态BiNode getTail(BiNode节点){//O(n) if(node==null){ 返回null; } while(node.node2!=null){ node=node.node2; } 返回节点; } 公共静态void concat(BiNode x,BiNode y){//O(1) x、 node2=y; y、 节点1=x; } 样本树: 4. / 3. / 2. / 1. 如您所见,在最坏的情况下(Big Oh不是一般情况),BST将仅使用node1分支进行构造。因此,递归必须使用“1+2+…+运行getTail()”N'完成转换的问题大小


也就是O(n^2)

如果我读对了这篇文章,那么在
getTail
中,一半的节点将必须遍历多达n/2个节点。这将给出
(n/2)*(n/2)
,也就是
(n^2)/4
,意思是O(n^2)。嗨,吉姆。谢谢你的回答,但我认为你是不对的。根必须遍历n/2个节点,二级节点只需遍历n/4个节点,…,因此我认为只有根必须遍历n/2个节点。谢谢。但我认为作者用O(n^2)表示平均时间。 SAMPLE TREE: 4 / 3 / 2 / 1