Ho implementato le mie proprie funzioni di tabella hash in C, ma attualmente non supporta il ridimensionamento. Mi stavo chiedendo quali algoritmi esistono oltre al modo bruto di creare una nuova tabella hash vuota e spostare tutto lì?Quali algoritmi sono disponibili per ridimensionare una tabella hash?
risposta
C'è un ridimensionamento incrementale.
Da Wikipedia:
incrementale ridimensionamento
Alcune implementazioni tabella hash, particolare nei sistemi in tempo reale, non può pagare il prezzo di allargare la tabella hash tutto in una volta, perché può interrupt operazioni critiche. Se uno non può evitare il ridimensionamento dinamico, una soluzione è quello di eseguire il ridimensionamento a poco a poco:
Durante il ridimensionamento, allocare la nuova tabella hash, ma mantenere il vecchio tavolo invariato. In ogni operazione di ricerca o cancellazione, controllare entrambe le tabelle. Esegue le operazioni di inserimento solo nella nuova tabella. Ad ogni inserimento si spostano anche gli elementi r dalla vecchia tabella alla nuova tabella . Quando tutti gli elementi vengono rimossi dalla vecchia tabella, rilasciarlo.
Per assicurarsi che la vecchia tabella sarà completamente copiato prima del nuovo tabella stessa deve essere allargata, si è necessario aumentare le dimensioni del tabella di un fattore di almeno (r + 1)/r durante il ridimensionamento.
Quindi questo non è un modo intelligente di spostare tutti gli elementi dal vecchio tavolo nella nuova tabella (e se ce n'è uno, non l'ho visto); piuttosto, alleggerisce l'onere del ridimensionamento consentendo che la migrazione avvenga gradualmente.
Wikipedia ha qualche words of wisdom sull'argomento.
Inoltre, non è una soluzione, ma potrebbe far parte di uno: se ci si trova in Windows è possibile utilizzare la famiglia di funzioni VirtualAlloc che consente di riservare lo spazio degli indirizzi senza impegnare effettivamente le pagine di memoria. Cioè, in parole povere, dovresti fare qualcosa come un "malloc" e dirgli di "prenotare 1000 MB, ma rendere solo i primi 10 disponibili". Quindi, se scriverai oltre i 10 MB, avresti il solito crash. Ma quando arriva il momento di espandersi, basta dire "OK, dammi un altro 10 MB dopo i primi". E i prossimi 10 MB sono resi disponibili all'indirizzo subito dopo i primi 10 MB. È come ridimensionare un array. L'attuale RAM in uso sarà sufficiente quanto necessario, ma gli indirizzi di memoria saranno riservati in anticipo in modo che altre operazioni di allocazione della memoria non li utilizzino.
Il solito errore è lasciare il codice cliente per indovinare il miglior numero di benne in anticipo. È utile, il cliente di solito ha una ragionevole ipotesi su quanti elementi finiranno nella tabella. Se vuoi farlo automaticamente, devi prima dichiarare una serie di numeri primi per le dimensioni della benna. Quando si vede il fattore di caricamento di un secchio troppo alto, selezionare il primo principale dell'array, ricreare l'elenco dei bucket e spostare gli elementi dai vecchi bucket alla nuova tabella.
- 1. quando ridimensionare una tabella hash?
- 2. - Quali opzioni sono disponibili?
- 3. Quali driver MySQL sono disponibili per node.js?
- 4. Quali strumenti sono disponibili per testare le prestazioni dell'istruzione SQL?
- 5. Quali ganci sono disponibili in jQuery?
- 6. Quali algoritmi comuni sono usati per C's rand()?
- 7. Creazione di una tabella hash/funzione hash
- 8. Come posso elencare gli algoritmi Cipher disponibili?
- 9. Quali operatori matematici sono disponibili in metaprogrammazione
- 10. Quali segnali Process.kill sono disponibili su Windows?
- 11. Attributi del nodo Chef. Quali sono disponibili?
- 12. Quali sono i buoni Podcast SQL disponibili?
- 13. Quali parser Java standalone sono disponibili?
- 14. Quali algoritmi utilizza SQL?
- 15. Quali sono le opzioni disponibili per Doctrine's Doctrine_Core :: generateModelsFromDb metodo?
- 16. Quali opzioni sono disponibili per automatizzare i collegamenti con NInject
- 17. Quali strumenti sono disponibili per la documentazione dei plugin jQuery?
- 18. Quali alternative sono disponibili controller SDN per POX?
- 19. Quali add-on/utilità sono disponibili per TFS?
- 20. Quali strutture dati sono disponibili nel kernel Linux
- 21. Quali strumenti sono disponibili per decodificare un database SQLite?
- 22. Quali framework di test unitari sono disponibili per l'assembler x86?
- 23. Quali librerie di oggetti di simulazione sono disponibili per D?
- 24. Quali pacchetti LaTeX sono disponibili per gli schemi circuitali?
- 25. Quali librerie iteratee/pipe ben sviluppate sono disponibili per Scala?
- 26. Quali strumenti sono disponibili per il refactoring di Ruby?
- 27. Quali plug-in vim sono disponibili per Eclipse?
- 28. Quali caratteri sono validi nelle chiavi hash?
- 29. Come calcolare le probabilità di una collisione negli algoritmi hash?
- 30. Quali sono gli hash delle opzioni?
Questo è un modo abbastanza intelligente per ridimensionare un array - se si dispone di spazio indirizzo da masterizzare (x64) - ma non funzionerà con le hash, sarà comunque necessario ripetere tutto (ed è più complesso farlo in posto.) – Eloff
@Eloff - Beh, come ho detto - non è una soluzione in sé, solo una parte di uno. E non devi prenotare molto più spazio per gli indirizzi. Solo una quantità ragionevole. Non è un proiettile d'argento, ma rende l'operazione di ridimensionamento più veloce. –
Vedo dove stai andando ora con questo, ma è dubbio che in realtà ridurrebbe il ridimensionamento più velocemente. La maggiore spesa qui non è l'allocazione della memoria, che presenta a malapena le caratteristiche. Tutto il tempo va in errori di pagina soft per portare la nuova memoria nello spazio di indirizzamento del processo (di solito accade nell'allocatore di memoria quando azzera la memoria) e nel costo richiesto per re-hash e reinserire tutti gli elementi nella hashtable . Ma per gli array dinamici, non è necessario copiare nulla e puoi pagare gli errori di pagina soft uno alla volta (crescendo di una pagina alla volta) ora è eccellente! – Eloff