J'ai récemment lu qu'il est possible d'avoir des tableaux qui n'ont pas besoin d'être initialisés, c'est-à-dire qu'il est possible de les utiliser sans avoir à passer du temps à essayer de définir chaque membre à la valeur par défaut. c'est-à-dire que vous pouvez commencer à utiliser le tableau comme s'il avait été initialisé par la valeur par défaut sans avoir à l'initialiser. (Désolé, je ne me souviens pas où j'ai lu ceci).
Par exemple, pourquoi cela peut être surprenant:
Dites que vous essayez de modéliser un pire cas Hashtable (pour chacun d' insertion / suppression / recherche) des entiers dans l'intervalle .[ 1 , n 2 ]
Vous pouvez allouer un tableau de taille bits et utiliser des bits individuels pour représenter l'existence d'un entier dans la table de hachage. Remarque: l'allocation de mémoire est considérée comme du temps .O ( 1 )
Maintenant, si vous n'aviez pas du tout à initialiser ce tableau, toute séquence d' opérations dites sur cette table de hachage est maintenant le pire des cas .O ( n )
Donc en fait, vous avez une implémentation de hachage "parfaite", qui pour une séquence de opérations utilise l' espace , mais s'exécute en temps !Θ ( n 2 ) O ( n )
Normalement, on s'attendrait à ce que votre temps d'exécution soit au moins aussi mauvais que votre utilisation de l'espace!
Remarque: L'exemple ci-dessus peut être utilisé pour une implémentation d'un ensemble clairsemé ou d'une matrice clairsemée, donc ce n'est pas seulement d'intérêt théorique, je suppose.
La question est donc:
Comment est-il possible d'avoir une structure de données de type tableau qui nous permet de sauter l'étape d'initialisation?
la source
Réponses:
Il s'agit d'une astuce très générale, qui peut être utilisée à d'autres fins que le hachage. Ci-dessous je donne une implémentation (en pseudo-code).
Soit trois vecteurs , P et V non initialisés de taille n chacun. Nous les utiliserons pour effectuer les opérations demandées par notre structure de données. Nous maintenons également une variable p o s . Les opérations sont mises en œuvre comme suit:UNE P V n p o s
Le tableau stocke simplement les valeurs transmises par la procédure s e t . Les tableaux V et P fonctionnent comme des certificats qui peuvent indiquer si une position donnée dans A a été initialisée.UNE s e t V P UNE
Notez qu'à chaque instant les éléments de allant de 0 à p o s - 1 sont initialisés. On peut donc utiliser en toute sécurité ces valeurs comme un certificat pour les valeurs initialisées en A . Pour chaque position i dans A initialisée, il y a un élément correspondant dans le vecteur P dont la valeur est égale à i . Ceci est indiqué par V [ i ] . Par conséquent, si nous regardons l'élément correspondant, P [ V [ i ] ] et sa valeur est iP 0 pos−1 A i A P i V[i] P[V[i]] i , nous savons que a été initialisé (puisque P ne ment jamais, car tous les éléments que nous considérons sont initialisés). De même, si A [ i ] n'est pas initialisé, alors V [ i ] peut pointer soit vers une position dans P en dehors de la plage 0 .. p o s - 1 , quand nous savons avec certitude qu'il n'est pas initialisé, ou peut pointer vers une position dans cette plage. Mais ce P [ j ] particulier correspond à une position différente dans A , et doncA[i] P A[i] V[i] P 0..pos−1 P[j] A , nous savons donc que A [ i ] n'a pas été initialisé.P[j]≠i A[i]
Il est facile de voir que toutes ces opérations se font en temps constant. De plus, l'espace utilisé est pour chacun des vecteurs, et O ( 1 ) pour la variable p o s , donc O ( n ) au total.O(n) O(1) pos O(n)
la source