Trova il k-esimo elemento più piccolo in un albero di ricerca binario in modo ottimale


112

Devo trovare il k-esimo elemento più piccolo nell'albero di ricerca binario senza utilizzare alcuna variabile statica / globale. Come ottenerlo in modo efficiente? La soluzione che ho in mente è fare l'operazione in O (n), il caso peggiore da quando ho intenzione di fare un attraversamento in ordine dell'intero albero. Ma in fondo sento che non sto usando la proprietà BST qui. La mia soluzione ipotetica è corretta o ce n'è una migliore disponibile?


7
L'albero è equilibrato?
kennytm

Non è. Ma se fosse equilibrato, esiste un modo ottimale?
bragboy

1
Se fai una ricerca su "Statistiche ordini" troverai quello che ti serve.
RAL

Sento in un certo senso la maggior parte delle risposte di seguito, mentre corrette sono barare in quanto utilizzano una variabile globale di qualche tipo (sia che si tratti di un riferimento a un numero intero o di una variabile che viene decrementata e restituita). Se assolutamente nessuno di questi è consentito, utilizzerei la ricorsione senza che vengano passati riferimenti.
Henley Chiu

Risposte:


170

Ecco solo uno schema dell'idea:

In un BST, la sottostruttura sinistra del nodo Tcontiene solo elementi più piccoli del valore memorizzato in T. Se kè inferiore al numero di elementi nella sottostruttura sinistra, il kesimo elemento più piccolo deve appartenere alla sottostruttura sinistra. Altrimenti, se kè più grande, il kesimo elemento più piccolo si trova nella sottostruttura destra.

Possiamo aumentare il BST in modo che ogni nodo in esso memorizzi il numero di elementi nel suo sottoalbero sinistro (supponiamo che il sottoalbero sinistro di un dato nodo includa quel nodo). Con questa informazione, è semplice attraversare l'albero chiedendo ripetutamente il numero di elementi nella sottostruttura sinistra, per decidere se ricorrere alla sottostruttura sinistra o destra.

Supponiamo ora di essere al nodo T:

  1. Se k == num_elements (sottoalbero sinistro di T) , la risposta che stiamo cercando è il valore in node T.
  2. Se k> num_elements (sottoalbero sinistro di T) , allora ovviamente possiamo ignorare il sottoalbero sinistro, perché anche quegli elementi saranno più piccoli del kesimo più piccolo. Quindi, riduciamo il problema a trovare l' k - num_elements(left subtree of T)elemento più piccolo della sottostruttura giusta.
  3. Se k <num_elements (sottoalbero sinistro di T) , allora il kesimo più piccolo è da qualche parte nel sottoalbero sinistro, quindi riduciamo il problema a trovare il kesimo elemento più piccolo nel sottoalbero sinistro.

Analisi della complessità:

Questo richiede O(depth of node)tempo, che è O(log n)nel peggiore dei casi con un BST bilanciato, o O(log n)in media per un BST casuale.

Una BST richiede O(n) memorizzazione e ne occorre un altro O(n)per memorizzare le informazioni sul numero di elementi. Tutte le operazioni BST richiedono O(depth of node)tempo e richiede O(depth of node)tempo aggiuntivo per mantenere le informazioni sul "numero di elementi" per l'inserimento, l'eliminazione o la rotazione dei nodi. Pertanto, la memorizzazione delle informazioni sul numero di elementi nella sottostruttura sinistra mantiene la complessità spaziale e temporale di un BST.


59
Per trovare l'ennesimo elemento più piccolo, è sufficiente memorizzare la dimensione del sottoalbero sinistro. Dovresti usare la dimensione del sottoalbero giusto se volessi anche trovare l'ennesimo elemento più grande. In realtà, puoi renderlo meno costoso: memorizza la dimensione totale dell'albero nella radice e la dimensione del sottoalbero sinistro. Quando è necessario ridimensionare il sottoalbero destro, è possibile sottrarre la dimensione della sinistra dalla dimensione totale.
Jerry Coffin

37
Tale BST aumentata è chiamato "albero delle statistiche degli ordini".
Daniel

10
@Ivlad: nel passaggio 2: Penso che "k - num_elements" dovrebbe essere "k - num_elements -1", poiché devi includere anche l'elemento radice.
understack

1
@understack - non se si presume che la radice faccia parte della sottostruttura.
IVlad

16
Se l'albero non contiene un campo contenente il "numero di elementi nella sua sottostruttura sinistra e destra", il metodo finirà per essere BigO (n) poiché dovrai percorrere la sottostruttura destra o sinistra in ogni nodo per calcola l'indice k del nodo corrente.
Robert S. Barnes,

68

Una soluzione più semplice sarebbe eseguire un attraversamento in ordine e tenere traccia dell'elemento attualmente da stampare (senza stamparlo). Quando raggiungiamo k, stampa l'elemento e salta il resto dell'attraversamento dell'albero.

void findK(Node* p, int* k) {
  if(!p || k < 0) return;
  findK(p->left, k);
  --k;
  if(k == 0) { 
    print p->data;
    return;  
  } 
  findK(p->right, k); 
}

1
+1: L'idea è nella giusta direzione, ma potrebbe essere necessario rafforzare alcune questioni in sospeso; vedi stackoverflow.com/a/23069077/278326
Arun

1
Mi piace questa soluzione, dato che BST è già ordinato, un attraversamento dovrebbe essere sufficiente.
Merlin

3
Se n è vicino al numero totale di nodi in questo albero, il tuo algoritmo impiegherà O (n) tempo per terminare, il che è negativo per la risposta selezionata-O (log n)
Spark8006

13
public int ReturnKthSmallestElement1(int k)
    {
        Node node = Root;

        int count = k;

        int sizeOfLeftSubtree = 0;

        while(node != null)
        {

            sizeOfLeftSubtree = node.SizeOfLeftSubtree();

            if (sizeOfLeftSubtree + 1 == count)
                return node.Value;
            else if (sizeOfLeftSubtree < count)
            {
                node = node.Right;
                count -= sizeOfLeftSubtree+1;
            }
            else
            {
                node = node.Left;
            }
        }

        return -1;
    }

questa è la mia implementazione in C # basata sull'algoritmo di cui sopra, ho pensato di postarla in modo che le persone possano capire meglio che funziona per me

grazie IVlad


11

Una soluzione più semplice sarebbe eseguire un attraversamento in ordine e tenere traccia dell'elemento attualmente da stampare con un contatore k. Quando raggiungiamo k, stampa l'elemento. Il runtime è O (n). Ricorda che il tipo di ritorno della funzione non può essere void, deve restituire il suo valore aggiornato di k dopo ogni chiamata ricorsiva. Una soluzione migliore a questo sarebbe un BST aumentato con un valore di posizione ordinato in ogni nodo.

public static int kthSmallest (Node pivot, int k){
    if(pivot == null )
        return k;   
    k = kthSmallest(pivot.left, k);
    k--;
    if(k == 0){
        System.out.println(pivot.value);
    }
    k = kthSmallest(pivot.right, k);
    return k;
}

Immagino che la tua soluzione sia migliore in termini di complessità dello spazio, rispetto al BST aumentato.
zach

La ricerca non si interrompe nemmeno dopo aver trovato l'elemento k-esimo più piccolo.
Vineeth Chitteti,

10

// aggiunge una versione java senza ricorsione

public static <T> void find(TreeNode<T> node, int num){
    Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();

    TreeNode<T> current = node;
    int tmp = num;

    while(stack.size() > 0 || current!=null){
        if(current!= null){
            stack.add(current);
            current = current.getLeft();
        }else{
            current = stack.pop();
            tmp--;

            if(tmp == 0){
                System.out.println(current.getValue());
                return;
            }

            current = current.getRight();
        }
    }
}

Mi piace questa soluzione e quella ricorsiva corrispondente. Onestamente, la maggior parte delle risposte a questa domanda sono troppo confuse / complesse da leggere.
Henley Chiu

Amo questa soluzione! Chiaro e fantastico!
Rugal

Questa soluzione è attraversare l'albero "in ordine" e diminuire un contatore dopo aver visitato il nodo, per poi fermarsi quando il contatore diventa uguale a zero. Il caso peggiore è quindi di ordine O (n). Non il confronto ottimale con le soluzioni ricorsive di @ IVlad il cui caso peggiore prende O (log n)
Jorge P.


4

Dato solo un semplice albero di ricerca binario, tutto ciò che puoi fare è iniziare dal più piccolo e spostarti verso l'alto per trovare il nodo giusto.

Se lo farai molto spesso, puoi aggiungere un attributo a ciascun nodo che indica quanti nodi sono nel suo sottoalbero sinistro. Usando quello, puoi discendere l'albero direttamente al nodo corretto.


4

Camminata in ordine ricorsiva con un contatore

Time Complexity: O( N ), N is the number of nodes
Space Complexity: O( 1 ), excluding the function call stack

L'idea è simile alla soluzione @prasadvk, ma presenta alcune lacune (vedi note sotto), quindi la pubblicherò come risposta separata.

// Private Helper Macro
#define testAndReturn( k, counter, result )                         \
    do { if( (counter == k) && (result == -1) ) {                   \
        result = pn->key_;                                          \
        return;                                                     \
    } } while( 0 )

// Private Helper Function
static void findKthSmallest(
    BstNode const * pn, int const k, int & counter, int & result ) {

    if( ! pn ) return;

    findKthSmallest( pn->left_, k, counter, result );
    testAndReturn( k, counter, result );

    counter += 1;
    testAndReturn( k, counter, result );

    findKthSmallest( pn->right_, k, counter, result );
    testAndReturn( k, counter, result );
}

// Public API function
void findKthSmallest( Bst const * pt, int const k ) {
    int counter = 0;
    int result = -1;        // -1 := not found
    findKthSmallest( pt->root_, k, counter, result );
    printf("%d-th element: element = %d\n", k, result );
}

Note (e differenze rispetto alla soluzione di @ prasadvk):

  1. if( counter == k )il test è richiesto in tre punti: (a) dopo il sottoalbero sinistro, (b) dopo il sottoalbero e (c) dopo il sottoalbero destro. Questo per garantire che l'elemento k-esimo venga rilevato per tutte le posizioni , cioè indipendentemente dalla sottostruttura in cui si trova.

  2. if( result == -1 )test richiesto per assicurarsi che venga stampato solo l'elemento risultato , altrimenti vengono stampati tutti gli elementi a partire dal k-esimo più piccolo fino alla radice.


La complessità temporale per questa soluzione è O(k + d), dov'è la dprofondità massima dell'albero. Pertanto utilizza una variabile globale counterma è illegale per questa domanda.
Valentin Shergin

Ciao Arun, puoi spiegare con un esempio. Non capisco questo in particolare il tuo primo punto.
Andy 897

3

Per l' albero di ricerca non equilibrato, ci vuole O (n) .

Per un albero di ricerca equilibrato , ci vuole O (k + log n) nel caso peggiore ma solo O (k) in Ammortizzato senso .

Avere e gestire il numero intero extra per ogni nodo: la dimensione del sottoalbero dà O (log n) complessità temporale . Tale albero di ricerca equilibrato è solitamente chiamato RankTree.

In generale, ci sono soluzioni (basate non su albero).

Saluti.


1

Funziona bene: status: è l'array che contiene se l'elemento viene trovato. k: è il k-esimo elemento da trovare. count: tiene traccia del numero di nodi attraversati durante l'attraversamento dell'albero.

int kth(struct tree* node, int* status, int k, int count)
{
    if (!node) return count;
    count = kth(node->lft, status, k, count);  
    if( status[1] ) return status[0];
    if (count == k) { 
        status[0] = node->val;
        status[1] = 1;
        return status[0];
    }
    count = kth(node->rgt, status, k, count+1);
    if( status[1] ) return status[0];
    return count;
}

1

Sebbene questa non sia sicuramente la soluzione ottimale al problema, è un'altra potenziale soluzione che ho pensato che alcune persone potrebbero trovare interessante:

/**
 * Treat the bst as a sorted list in descending order and find the element 
 * in position k.
 *
 * Time complexity BigO ( n^2 )
 *
 * 2n + sum( 1 * n/2 + 2 * n/4 + ... ( 2^n-1) * n/n ) = 
 * 2n + sigma a=1 to n ( (2^(a-1)) * n / 2^a ) = 2n + n(n-1)/4
 *
 * @param t The root of the binary search tree.
 * @param k The position of the element to find.
 * @return The value of the element at position k.
 */
public static int kElement2( Node t, int k ) {
    int treeSize = sizeOfTree( t );

    return kElement2( t, k, treeSize, 0 ).intValue();
}

/**
 * Find the value at position k in the bst by doing an in-order traversal 
 * of the tree and mapping the ascending order index to the descending order 
 * index.
 *
 *
 * @param t Root of the bst to search in.
 * @param k Index of the element being searched for.
 * @param treeSize Size of the entire bst.
 * @param count The number of node already visited.
 * @return Either the value of the kth node, or Double.POSITIVE_INFINITY if 
 *         not found in this sub-tree.
 */
private static Double kElement2( Node t, int k, int treeSize, int count ) {
    // Double.POSITIVE_INFINITY is a marker value indicating that the kth 
    // element wasn't found in this sub-tree.
    if ( t == null )
        return Double.POSITIVE_INFINITY;

    Double kea = kElement2( t.getLeftSon(), k, treeSize, count );

    if ( kea != Double.POSITIVE_INFINITY )
        return kea;

    // The index of the current node.
    count += 1 + sizeOfTree( t.getLeftSon() );

    // Given any index from the ascending in order traversal of the bst, 
    // treeSize + 1 - index gives the
    // corresponding index in the descending order list.
    if ( ( treeSize + 1 - count ) == k )
        return (double)t.getNumber();

    return kElement2( t.getRightSon(), k, treeSize, count );
}

1

firma:

Node * find(Node* tree, int *n, int k);

chiama come:

*n = 0;
kthNode = find(root, n, k);

definizione:

Node * find ( Node * tree, int *n, int k)
{
   Node *temp = NULL;

   if (tree->left && *n<k)
      temp = find(tree->left, n, k);

   *n++;

   if(*n==k)
      temp = root;

   if (tree->right && *n<k)
      temp = find(tree->right, n, k);

   return temp;
}

1

Bene, ecco i miei 2 centesimi ...

int numBSTnodes(const Node* pNode){
     if(pNode == NULL) return 0;
     return (numBSTnodes(pNode->left)+numBSTnodes(pNode->right)+1);
}


//This function will find Kth smallest element
Node* findKthSmallestBSTelement(Node* root, int k){
     Node* pTrav = root;
     while(k > 0){
         int numNodes = numBSTnodes(pTrav->left);
         if(numNodes >= k){
              pTrav = pTrav->left;
         }
         else{
              //subtract left tree nodes and root count from 'k'
              k -= (numBSTnodes(pTrav->left) + 1);
              if(k == 0) return pTrav;
              pTrav = pTrav->right;
        }

        return NULL;
 }

0

Questo è quello che ho pensato e funziona. Verrà eseguito in o (log n)

public static int FindkThSmallestElemet(Node root, int k)
    {
        int count = 0;
        Node current = root;

        while (current != null)
        {
            count++;
            current = current.left;
        }
        current = root;

        while (current != null)
        {
            if (count == k)
                return current.data;
            else
            {
                current = current.left;
                count--;
            }
        }

        return -1;


    } // end of function FindkThSmallestElemet

3
non penso che questa soluzione funzionerà. E se il K-esimo più piccolo si trova nel sottoalbero destro del nodo dell'albero?
Anil Vishnoi

0

Bene, possiamo semplicemente usare l'attraversamento in ordine e spingere l'elemento visitato su una pila. pop k numero di volte, per ottenere la risposta.

possiamo anche fermarci dopo k elementi


1
questa non è una soluzione ottimale
bragboy

0

Soluzione per il caso BST completo: -

Node kSmallest(Node root, int k) {
  int i = root.size(); // 2^height - 1, single node is height = 1;
  Node result = root;
  while (i - 1 > k) {
    i = (i-1)/2;  // size of left subtree
    if (k < i) {
      result = result.left;
    } else {
      result = result.right;
      k -= i;
    }  
  }
  return i-1==k ? result: null;
}

0

Il kernel Linux ha un'eccellente struttura dati ad albero rosso-nero aumentata che supporta operazioni basate sui ranghi in O (log n) in linux / lib / rbtree.c.

Un port Java molto grezzo può anche essere trovato su http://code.google.com/p/refolding/source/browse/trunk/core/src/main/java/it/unibo/refolding/alg/RbTree.java , insieme a RbRoot.java e RbNode.java. L'elemento n-esimo può essere ottenuto chiamando RbNode.nth (nodo RbNode, int n), passando nella radice dell'albero.


0

Ecco una versione concisa in C # che restituisce il k-esimo elemento più piccolo, ma richiede il passaggio di k come argomento ref (è lo stesso approccio di @prasadvk):

Node FindSmall(Node root, ref int k)
{
    if (root == null || k < 1)
        return null;

    Node node = FindSmall(root.LeftChild, ref k);
    if (node != null)
        return node;

    if (--k == 0)
        return node ?? root;
    return FindSmall(root.RightChild, ref k);
}

È O (log n) per trovare il nodo più piccolo, e quindi O (k) per attraversare il nodo k-esimo, quindi è O (k + log n).


che ne dici della versione Java?
Henley Chiu


0

Non sono riuscito a trovare un algoritmo migliore .. quindi ho deciso di scriverne uno :) Correggimi se questo è sbagliato.

class KthLargestBST{
protected static int findKthSmallest(BSTNode root,int k){//user calls this function
    int [] result=findKthSmallest(root,k,0);//I call another function inside
    return result[1];
}
private static int[] findKthSmallest(BSTNode root,int k,int count){//returns result[]2 array containing count in rval[0] and desired element in rval[1] position.
    if(root==null){
        int[]  i=new int[2];
        i[0]=-1;
        i[1]=-1;
        return i;
    }else{
        int rval[]=new int[2];
        int temp[]=new int[2];
        rval=findKthSmallest(root.leftChild,k,count);
        if(rval[0]!=-1){
            count=rval[0];
        }
        count++;
        if(count==k){
            rval[1]=root.data;
        }
        temp=findKthSmallest(root.rightChild,k,(count));
        if(temp[0]!=-1){
            count=temp[0];
        }
        if(temp[1]!=-1){
            rval[1]=temp[1];
        }
        rval[0]=count;
        return rval;
    }
}
public static void main(String args[]){
    BinarySearchTree bst=new BinarySearchTree();
    bst.insert(6);
    bst.insert(8);
    bst.insert(7);
    bst.insert(4);
    bst.insert(3);
    bst.insert(4);
    bst.insert(1);
    bst.insert(12);
    bst.insert(18);
    bst.insert(15);
    bst.insert(16);
    bst.inOrderTraversal();
    System.out.println();
    System.out.println(findKthSmallest(bst.root,11));
}

}


0

Ecco il codice java,

max (Radice nodo, int k) - per trovare il k -esimo più grande

min (Node root, int k) - per trovare kth Smallest

static int count(Node root){
    if(root == null)
        return 0;
    else
        return count(root.left) + count(root.right) +1;
}
static int max(Node root, int k) {
    if(root == null)
        return -1;
    int right= count(root.right);

    if(k == right+1)
        return root.data;
    else if(right < k)
        return max(root.left, k-right-1);
    else return max(root.right, k);
}

static int min(Node root, int k) {
    if (root==null)
        return -1;

    int left= count(root.left);
    if(k == left+1)
        return root.data;
    else if (left < k)
        return min(root.right, k-left-1);
    else
        return min(root.left, k);
}

0

anche questo funzionerebbe. basta chiamare la funzione con maxNode nell'albero

def k_largest (self, node, k): if k <0: return None
if k == 0: return node else: k - = 1 return self.k_largest (self.predecessor (node), k)


0

Penso che questo sia migliore della risposta accettata perché non è necessario modificare il nodo dell'albero originale per memorizzare il numero dei suoi nodi figli.

Dobbiamo solo usare l'attraversamento in ordine per contare il nodo più piccolo da sinistra a destra, interrompere la ricerca quando il conteggio è uguale a K.

private static int count = 0;
public static void printKthSmallestNode(Node node, int k){
    if(node == null){
        return;
    }

    if( node.getLeftNode() != null ){
        printKthSmallestNode(node.getLeftNode(), k);
    }

    count ++ ;
    if(count <= k )
        System.out.println(node.getValue() + ", count=" + count + ", k=" + k);

    if(count < k  && node.getRightNode() != null)
        printKthSmallestNode(node.getRightNode(), k);
}

0

L'approccio migliore è già presente, ma vorrei aggiungere un semplice codice per questo

int kthsmallest(treenode *q,int k){
int n = size(q->left) + 1;
if(n==k){
    return q->val;
}
if(n > k){
    return kthsmallest(q->left,k);
}
if(n < k){
    return kthsmallest(q->right,k - n);
}

}

int size(treenode *q){
if(q==NULL){
    return 0;
}
else{
    return ( size(q->left) + size(q->right) + 1 );
}}

0

Utilizzando la classe Result ausiliaria per tenere traccia se il nodo viene trovato e l'attuale k.

public class KthSmallestElementWithAux {

public int kthsmallest(TreeNode a, int k) {
    TreeNode ans = kthsmallestRec(a, k).node;
    if (ans != null) {
        return ans.val;
    } else {
        return -1;
    }
}

private Result kthsmallestRec(TreeNode a, int k) {
    //Leaf node, do nothing and return
    if (a == null) {
        return new Result(k, null);
    }

    //Search left first
    Result leftSearch = kthsmallestRec(a.left, k);

    //We are done, no need to check right.
    if (leftSearch.node != null) {
        return leftSearch;
    }

    //Consider number of nodes found to the left
    k = leftSearch.k;

    //Check if current root is the solution before going right
    k--;
    if (k == 0) {
        return new Result(k - 1, a);
    }

    //Check right
    Result rightBalanced = kthsmallestRec(a.right, k);

    //Consider all nodes found to the right
    k = rightBalanced.k;

    if (rightBalanced.node != null) {
        return rightBalanced;
    }

    //No node found, recursion will continue at the higher level
    return new Result(k, null);

}

private class Result {
    private final int k;
    private final TreeNode node;

    Result(int max, TreeNode node) {
        this.k = max;
        this.node = node;
    }
}
}

0

Complessità temporale della soluzione Python: O (n) Complessità spaziale: O (1)

L'idea è di utilizzare Morris Inorder Traversal

class Solution(object):
def inorderTraversal(self, current , k ):
    while(current is not None):    #This Means we have reached Right Most Node i.e end of LDR traversal

        if(current.left is not None):  #If Left Exists traverse Left First
            pre = current.left   #Goal is to find the node which will be just before the current node i.e predecessor of current node, let's say current is D in LDR goal is to find L here
            while(pre.right is not None and pre.right != current ): #Find predecesor here
                pre = pre.right
            if(pre.right is None):  #In this case predecessor is found , now link this predecessor to current so that there is a path and current is not lost
                pre.right = current
                current = current.left
            else:                   #This means we have traverse all nodes left to current so in LDR traversal of L is done
                k -= 1
                if(k == 0):
                    return current.val
                pre.right = None       #Remove the link tree restored to original here 
                current = current.right
        else:               #In LDR  LD traversal is done move to R 
            k -= 1
            if(k == 0):
                return current.val
            current = current.right

    return 0

def kthSmallest(self, root, k):
    return self.inorderTraversal( root , k  )

-1

ho scritto una bella funzione per calcolare il k-esimo elemento più piccolo. Uso l'attraversamento in ordine e si ferma quando raggiunge il k-esimo elemento più piccolo.

void btree::kthSmallest(node* temp, int& k){
if( temp!= NULL)   {
 kthSmallest(temp->left,k);       
 if(k >0)
 {
     if(k==1)
    {
      cout<<temp->value<<endl;
      return;
    }

    k--;
 }

 kthSmallest(temp->right,k);  }}

Nessuna metrica fornita sul motivo per cui questo è ottimale. In entrambi i casi grandi e piccoli
Woot4Moo

-1
int RecPrintKSmallest(Node_ptr head,int k){
  if(head!=NULL){
    k=RecPrintKSmallest(head->left,k);
    if(k>0){
      printf("%c ",head->Node_key.key);
      k--;
    }
    k=RecPrintKSmallest(head->right,k);
  }
  return k;
}

2
Si prega di accompagnare sempre il codice con un certo livello di descrizione su cosa fa e su come aiuta a risolvere il problema.
Ren

-1
public TreeNode findKthElement(TreeNode root, int k){
    if((k==numberElement(root.left)+1)){
        return root;
    }
    else if(k>numberElement(root.left)+1){
        findKthElement(root.right,k-numberElement(root.left)-1);
    }
    else{
        findKthElement(root.left, k);
    }
}

public int numberElement(TreeNode node){
    if(node==null){
        return 0;
    }
    else{
        return numberElement(node.left) + numberElement(node.right) + 1;
    }
}

-1
public static Node kth(Node n, int k){
    Stack<Node> s=new Stack<Node>();
    int countPopped=0;
    while(!s.isEmpty()||n!=null){
      if(n!=null){
        s.push(n);
        n=n.left;
      }else{
        node=s.pop();
        countPopped++;
        if(countPopped==k){
            return node;
        }
        node=node.right;

      }
  }

}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.