Quelle est la différence entre le nœud * et le nœud **? Quand dois-je utiliser le nœud * et quand dois-je utiliser le nœud ** pour insérer le nœud dans une liste chaînée?


Réponse 1:

Je suppose que le nœud est un type défini par l'utilisateur basé sur une forme de classe ou une structure.

  1. node * signifie pointeur sur un objet node. Vous avez besoin du pointeur node * pour parcourir le listnode lié ** signifie un double pointeur vers un pointeur unique qui pointe vers un objet node. Vous avez besoin du pointeur node ** pour que la tête d'une liste liée à la portée de l'appelant pointe vers autre chose (comme un nouveau nœud lorsque vous ajoutez un nœud en avant dans la liste liée ou pointe vers NULL lorsque vous supprimez le seul élément présent dans la liste chaînée)

Par exemple, considérez la fonction d'insertion ci-dessous,

insert vide (node ​​** head, int value)
{
    node * new_node = nouveau nœud
    noeud * dernier = * tête;
    new_node-> data = value;
 
    new_node-> next = NULL;
    if (* head == NULL)
    {
       * head = new_node;
       revenir;
    }
 
    while (last-> next! = NULL)
        dernier = dernier-> suivant;
 
    last-> next = new_node;
    revenir;
}

Ainsi, lorsque la fonction ci-dessus est appelée et si vous avez utilisé node * au lieu de node ** pour head dans le paramètre de fonction, les modifications apportées au pointage par le pointeur head dans la portée de la fonction ne seront pas reflétées dans la variable réelle du pointeur head présente à l'appelant portée. Cela se produira car lorsque vous écrivez l'argument node * head à l'intérieur de la fonction, la valeur d'adresse sera transmise à partir de la fonction appelante qui sera stockée à l'intérieur de node * head. Ainsi, tout changement futur au sein de la fonction, comme faire en sorte que node * head pointe vers autre chose, sera effectué sur node * head présent dans la portée de la fonction au lieu de node * head présent dans la portée de l'appelant.

Par conséquent, lorsque vous souhaitez modifier le pointeur de tête réel présent à la portée de l'appelant pour pointer autre chose, vous devez passer l'adresse du pointeur de tête réel à un argument de fonction de pointeur double. Ainsi, comme dans le code ci-dessus, dans le bloc if, vous pouvez voir en utilisant * head que vous pouvez rendre le pointeur de tête réel présent à la portée de l'appelant pour pointer NULL.

Le concept ci-dessus peut être appliqué de manière similaire à une fonction de suppression pour une liste chaînée.

La ligne de fond est "Les modifications apportées pour pointer vers un paramètre de fonction de pointeur unique ne seront pas reflétées dans la portée de l'appelant. Vous pouvez manipuler les objets ou les valeurs pointés par le noeud * depuis la fonction interne, mais vous ne pouvez pas manipuler le pointeur présent à la portée de l'appelant pour pointer autre chose en utilisant simplement le noeud *. Par conséquent, vous utilisez le nœud ** pour manipuler les pointeurs à la portée de l'appelant et le nœud * pour manipuler les objets à la portée de l'appelant ».

PS:

Généralement partout, les codeurs utilisent node ** pour pointer le pointeur de tête et node * pour itérer. Cela ne signifie pas que vous ne pouvez pas parcourir la liste liée à l'aide du nœud **. Tout ce qui peut être réalisé par le nœud * peut également l'être par le nœud **. Il rend simplement plus simple et plus propre l'utilisation de node * pour les choses d'itération tandis que node ** pour manipuler les têtes.