Временная сложность построения BST с использованием предзаказа

Я попытался написать программу для построения бинарного дерева поиска, используя последовательность предварительного заказа. Я знаю, что есть много решений: алгоритм min / max, классическая (или "очевидная" рекурсия) или даже итерация, а не рекурсия.

Я попытался реализовать классическую рекурсию: первый элемент обхода предварительного заказа - это корень. Затем я ищу все элементы, которые меньше, чем корень. Все эти элементы будут частью левого поддерева, а другие значения будут частью правого поддерева. Я повторяю это, пока я не построю все поддеревья. Это очень классический подход.

Вот мой код:

public static TreeNode constructInOrderTree(int[] inorder) { 
    return constructInOrderTree(inorder, 0, inorder.length-1);
}

 private static TreeNode constructInOrderTree(int[] inorder, int start, int end){
 if(start>end){
        return null;
 }

int rootValue = inorder[start];
TreeNode root = new TreeNode(rootValue);

int k = 0; 
for (int i =0; i< inorder.length; i++){
    if (inorder[i]<= rootValue){ 
        k=i;
    }
}

 root.left = constructInOrderTree(inorder, start+1, k);
 root.right= constructInOrderTree(inorder, k+1, end);

    return root;
   }

Мой вопрос: какова временная сложность этого алгоритма? Это O(n^2) или O(n * log(n))?

Я искал здесь в stackru, но я нашел много противоречивых ответов. Иногда кто-то говорил, что это O(n^2), иногда O (n * log (n)), и я действительно путался.

Можем ли мы применить основную теорему здесь? Если да, "возможно", мы можем считать, что каждый раз, когда мы делим дерево на два поддерева (равных частей), у нас будет отношение: (O(n) - сложность поиска в массиве)

T (n) = 1/2 * T (n / 2) + O (n)

Что даст нам сложность O(n*log(n)), Но это не совсем верно, я думаю, что мы не делим дерево на равные части, потому что мы ищем в массиве, пока мы не нашли адекватных элементов нет?

Можно ли здесь применить основную теорему?

1 ответ

Forethoughts:

Нет, это не O(n^2)ни O(nlogn) в туалете. Из-за природы деревьев и того факта, что вы не выполняете никаких сложных действий с каждым элементом. Все, что вы делаете, это выводите его, в отличие от сортировки с некоторым алгоритмом сравнения.

Тогда туалет будет O(n),

То есть когда дерево перекошено, то есть одно из поддеревьев корня пусто. Тогда у вас есть квази простой связанный список. Затем, чтобы вывести его, вы должны посетить каждый элемент хотя бы один раз, давая O(n),

Доказательство:

Предположим, что правое поддерево пусто, а усилие на вызов постоянно (только распечатка). затем

T(n) = T(n-1) + T(0) + c
T(n) = T(n-2) + 2T(0) + 2c
.
.
T(n) = nT(0) + nc = n(T(0) + c)

поскольку T(0) а также c константы, вы в конечном итоге O(n),

Другие вопросы по тегам