2012-05-30 2 views
1

У меня есть следующий правильный Java-код, чтобы найти in-order k-й элемент в двоичном дереве.Как написать рекурсию без использования поля класса в Java

private static int count = 0; 
public static <T> T findkthInOrder(Node<T> root, int k) { 
    count=0; 
    return findkthInOrder(root, k, 0); 
} 
public static <T> T findkthInOrder(Node<T> root, int k,int a) { 
    if (root == null) 
     return null; 
    T rt = findkthInOrder(root.left, k, 0); 
    if (rt != null) 
     return rt; 
    count++; 
    if (count == k) { 
     return root.data; 
    } 
    return findkthInOrder(root.right, k, 0); 
} 

Но я действительно хочу, чтобы удалить использование count, возможно, путем использования дополнительного аргумента метода. Я также хочу сохранить его как рекурсию и потребовать метод findkthInOrder для возврата значения типа T.

Может ли кто-нибудь помочь мне в этом? Спасибо.

+2

это домашнее задание? похоже, ваш профессор оставил ключ для вашего кода. – jdigital

+0

@jdigital: нет, это не домашнее задание. Это то, что я практикую самостоятельно. Скажите, пожалуйста, ваше наблюдение. –

+0

Подсказка: какой параметр 'a'? – jdigital

ответ

0

Это избыточно, но здесь идет ... Единственный изменяемый номер классом я мог бы найти в Java был java.util.concurrent.atomic.AtomicInteger

public static <T> T findkthInOrder(Node<T> root, int k) { 
    return findkthInOrder(root, k, new AtomicInteger(0)); 
} 
public static <T> T findkthInOrder(Node<T> root, int k, AtomicInteger count) { 
    if (root == null) 
     return null; 
    T rt = findkthInOrder(root.left, k, count); 
    if (rt != null) 
     return rt; 
    if (count.incrementAndGet() == k) { 
     return root.data; 
    } 
    return findkthInOrder(root.right, k, count); 
} 

я сделал преждевременную оптимизацию, теперь исправлен.

Вот альтернативное решение:

public static <T> T findkthInOrder(Node<T> root, int k) { 
    return findkthInOrder(root, k, new int[]{0}); 
} 
public static <T> T findkthInOrder(Node<T> root, int k, int[] count) { 
    if (root == null) 
     return null; 
    T rt = findkthInOrder(root.left, k, count); 
    if (rt != null) 
     return rt; 
    count[0]++; 
    if (count[0] == k) { 
     return root.data; 
    } 
    return findkthInOrder(root.right, k, count); 
} 
+0

да, это будет работать. –

+0

Да, это действительно излишне использовать AtomicInteger. Думаю, мне придется использовать некоторый не-неизменяемый счетчик как аргумент метода, чтобы заставить его работать, правда? Простой аргумент 'int count' в качестве аргумента не заставит его работать КОГДА-ЛИБО? –

+0

Это правильно. Другое решение - изменить 'new AtomicInteger (0)' на 'new int [] {0}' ... Вы получаете идею – user845279

0

Инкапсулировать значение счета в объекте (Integer нецелесообразно, так как он не может быть включен).

Оставить заявку add(int), чтобы увеличить счет; другой, чтобы получить текущее значение.

Передать объект рекурсивно.

+0

Вы казались правильными. Это единственный путь? –

+0

Вам нужно знать, сколько элементов проходят рекурсивные вызовы. Либо вы это делаете, либо древовидная структура предоставляет вам способ узнать, сколько узлов имеет поддерево, или вы изменяете свой возвращаемый параметр, чтобы вернуть количество оцениваемых узлов вместе с результатом. – SJuan76

0
public class Node<T> { 
    T tData; 
    Node<T> ntLeft, ntRight; 
    int iSubtreeCount; 
    public Node(T tData, Node<T> ntLeft, Node<T> ntRight) { 
     this.tData = tData; 
     this.ntLeft = ntLeft; 
     this.ntRight = ntRight; 
     this.iSubtreeCount = subCount(ntLeft) + subCount(ntRight) + 1; 
    } 
    public static int subCount(Node<T> nt) { 
     return null == nt ? 0 : nt.getSubtreeCount(); 
    } 
    public int getSubtreeCount() { return iSubtreeCount; } 
    public Node<T> getLeft() { return ntLeft; } 
    public Node<T> getRight() { return ntRight; } 
    public T getData() { return tData; } 
} 

И ваша рутина:

public static <T> T findKth(Node<T> ntInput, int k) { 
    if (0 == k || null == ntInput) 
     return null; 
    else if (Node.subCount(ntInput.getLeft()) > k - 1) 
     return findKth(ntInput.getLeft(), k); 
    else if (Node.subCount(ntInput.getLeft()) == k - 1) 
     return ntInput.getData(); 
    else 
     return findKth(ntInput.getRight(), k - 1 - Node.subCount(ntInput.getLeft())); 
} 
Смежные вопросы