Dato il seguente problema:Conservare il più grande 5000 numeri da un flusso di numeri
"Store più grandi 5000 numeri da un flusso di numeri"
La soluzione che viene in mente è una albero di ricerca binario che mantiene un conteggio del numero di nodi nell'albero e un riferimento al nodo più piccolo una volta che il conteggio raggiunge 5000. Quando il conteggio raggiunge 5000, ogni nuovo numero da aggiungere può essere confrontato con l'elemento più piccolo nell'albero. Se maggiore, è possibile aggiungere il nuovo numero, quindi il più piccolo rimosso e il nuovo più piccolo calcolato (che dovrebbe essere molto semplice avendo già il più piccolo precedente).
La mia preoccupazione per questa soluzione è che l'albero binario sarà naturalmente distorto (dato che sto cancellando solo da un lato).
C'è un modo per risolvere questo problema che non creerà un albero terribilmente distorto?
Nel caso qualcuno lo vuole, ho incluso pseudo-codice per la mia soluzione in modo molto più in basso:
process(number)
{
if (count == 5000 && number > smallest.Value)
{
addNode(root, number)
smallest = deleteNodeAndGetNewSmallest (root, smallest)
}
}
deleteNodeAndGetNewSmallest(lastSmallest)
{
if (lastSmallest has parent)
{
if (lastSmallest has right child)
{
smallest = getMin(lastSmallest.right)
lastSmallest.parent.right = lastSmallest.right
}
else
{
smallest = lastSmallest.parent
}
}
else
{
smallest = getMin(lastSmallest.right)
root = lastSmallest.right
}
count--
return smallest
}
getMin(node)
{
if (node has left)
return getMin(node.left)
else
return node
}
add(number)
{
//standard implementation of add for BST
count++
}
È possibile utilizzare una struttura di ricerca bilanciata come AVL o simile (https://en.wikipedia.org/wiki/AVL_tree). Ma una soluzione basata su heap è più naturale. –