Le temps de revenir en arrière dans le temps pour une leçon. Alors que nous ne pense pas à ces choses dans notre fantaisie géré langues aujourd'hui, ils sont construits sur la même base, voyons donc comment la mémoire est gérée en C.
Avant de plonger dans, une explication rapide de ce que le terme de "pointeur". Un pointeur est simplement une variable "points" pour un emplacement dans la mémoire. Il ne contient pas la valeur réelle à cette zone de la mémoire, il contient l'adresse de la mémoire. Pensez à un bloc de la mémoire comme une boîte aux lettres. Le pointeur serait l'adresse de la boîte aux lettres.
En C, un tableau est simplement un pointeur avec un décalage, le décalage précise dans quelle mesure en mémoire à regarder. Cette offre O(1) temps d'accès.
MyArray [5]
^ ^
Pointer Offset
Toutes les autres structures de données, soit de construire sur ce, ou de ne pas utiliser adjacentes de la mémoire pour le stockage, ce qui entraîne un mauvais accès aléatoire regarder de temps (même Si il y a d'autres avantages à ne pas utiliser sequential memory).
Par exemple, disons que nous avons un tableau avec 6 numéros (6,4,2,3,1,5), à la mémoire, elle devrait ressembler à ceci:
=====================================
| 6 | 4 | 2 | 3 | 1 | 5 |
=====================================
Dans un tableau, nous savons que chaque élément est à côté les uns des autres dans la mémoire. Un C array (Appelé MyArray ici) est tout simplement un pointeur vers le premier élément:
=====================================
| 6 | 4 | 2 | 3 | 1 | 5 |
=====================================
^
MyArray
Si nous voulions chercher Montableau[4], à l'interne, il serait accessible comme ceci:
0 1 2 3 4
=====================================
| 6 | 4 | 2 | 3 | 1 | 5 |
=====================================
^
MyArray + 4 ---------------/
(Pointer + Offset)
Car on peut directement accéder à un élément du tableau en ajoutant le décalage du pointeur, on peut trouver n'importe quel élément dans le même laps de temps, indépendamment de la taille de la matrice. Cela signifie que l'obtention d'Montableau[1000] prendrait la même quantité de temps que l'obtention de la Montableau[5].
Une alternative structure de données est une liste liée. C'est une liste linéaire de pointeurs, chacun pointant vers le nœud suivant
======== ======== ======== ======== ========
| Data | | Data | | Data | | Data | | Data |
| | -> | | -> | | -> | | -> | |
| P1 | | P2 | | P3 | | P4 | | P5 |
======== ======== ======== ======== ========
P(X) stands for Pointer to next node.
Notez que j'ai fait chaque "nœud" dans son propre bloc. C'est parce qu'ils ne sont pas garantis d'être (et de plus ne sera probablement pas) adjacents dans la mémoire.
Si je veux accéder à P3, je ne peux pas accéder directement, parce que je ne sais pas où il est dans la mémoire. Tout ce que je sais où est la racine (P1) est, donc je dois commencer à P1, et de suivre chaque pointeur vers le nœud désiré.
C'est un O(N) temps (Les hausses des coûts de chaque élément est ajouté). Il est beaucoup plus coûteux P1000 par rapport à l'obtention de P4.
Niveau plus élevé de structures de données, telles que les tables de hachage, les piles et les files d'attente, tous peuvent utiliser un tableau (ou de plusieurs tableaux) à l'intérieur des Listes et Arbres Binaires utilisent généralement des nœuds et des pointeurs.
Vous pourriez vous demander pourquoi quelqu'un serait d'utiliser une structure de données qui nécessite linéaire de la traversée de la valeur plutôt que de simplement en utilisant un tableau, mais ils ont leurs usages.
Prendre notre gamme de nouveau. Cette fois, je veux trouver l'élément du tableau qui contient la valeur 5.
=====================================
| 6 | 4 | 2 | 3 | 1 | 5 |
=====================================
^ ^ ^ ^ ^ FOUND!
Dans cette situation, je ne sais pas ce décalage à ajouter à le pointeur de la trouver, j'ai donc commencer à 0, et de travailler mon chemin jusqu'à jusqu'à ce que je le trouve. Cela signifie que je dois effectuer 6 contrôles.
De ce fait, la recherche d'une valeur dans un tableau est considéré comme O(N). Le coût de la recherche augmente à mesure que le tableau devient plus grand.
Rappelez-vous, au-dessus où j'ai dit que, parfois, l'aide d'un non séquentiel structure de données peut avoir des avantages? La recherche de données est l'un de ces avantages et l'un des meilleurs exemples est l'Arbre Binaire.
Un Arbre Binaire est une structure de données similaire à une liste liée, cependant au lieu de le relier à un seul nœud, chaque nœud peut relier deux nœuds enfants.
==========
| Root |
==========
/ \
========= =========
| Child | | Child |
========= =========
/ \
========= =========
| Child | | Child |
========= =========
Assume that each connector is really a Pointer
Lorsque les données sont insérées dans un arbre binaire, il utilise plusieurs règles de décider où placer le nouveau nœud. Le concept de base est que si la nouvelle valeur est plus grande que les parents, il l'insère à la gauche, si elle est inférieure, il l'insère à droite.
Cela signifie que les valeurs dans un arbre binaire pourrait ressembler à ceci:
==========
| 100 |
==========
/ \
========= =========
| 200 | | 50 |
========= =========
/ \
========= =========
| 75 | | 25 |
========= =========
Lors de la recherche un arbre binaire de la valeur de 75, nous avons seulement besoin pour visiter les 3 noeuds ( O(log N) ), en raison de cette structure:
- Est de 75 à moins de 100? Regardez Droit Nœud
- Est de 75 à plus de 50? Regardez Nœud de Gauche
- Il est le 75!
Même s'il est de 5 nœuds dans notre arbre, nous n'avons pas besoin de regarder les deux autres, parce que nous savions qu'ils (et leurs enfants) ne pouvait pas contenir la valeur que nous recherchions. Cela nous donne un temps de recherche qu'au pire des cas signifie que nous avons de visiter chaque nœud, mais dans le meilleur des cas, nous n'avez qu'à visiter une petite partie des nœuds.
C'est là que les tableaux se faire battre, ils fournissent une constante O(N) le temps de recherche, en dépit de O(1) temps d'accès.
C'est un très haut de niveau vue d'ensemble sur les structures de données en mémoire, sautant sur beaucoup de détails, mais j'espère qu'il illustre un tableau de la force et de faiblesse par rapport à d'autres structures de données.