2010-12-08 7 views
0

Étant donné seulement un pointeur vers le noeud à supprimer, comment supprimer le noeud dans la liste chaînée ...?Suppression d'une liste chaînée

+1

liste chaînée Singly? Liste doublement liée? – Jon

+3

Si liste chaînée unique puis dupliquer: http://stackoverflow.com/questions/1960562/delete-a-node-in-singly-link-list Si liste doublement chaînée ...Il ne vaut pas la peine de poser une question dans l'interview :) – codaddict

+1

En outre, la solution de cette copie est un hack laid si l'objet de la liste est quelque chose de grand (constructeur de copie non-trivial ou juste coûteux). Voir le post de codaddict ici. Les questions d'entrevue peu pratiques sont peu pratiques. :) – Kos

Répondre

6

La question est trop ambiguë, et est probablement de ce type pour une raison (par exemple, engendrer une conversation au lieu de tester votre connaissance réelle de la structure de données). Ils s'attendent probablement à ce que vous demandiez "Est-ce une liste doublement liée ou une liste unidirectionnelle?" Si elle est une liste doublement liée, c'est une question simple:

curr->prev->next = curr->next; 
curr->next->prev = curr->prev; 
delete curr; 

Si elle est une liste chaînée, vous devez avoir le nœud de tête afin que vous puissiez trouver le nœud précédent dans la liste. Donc, ils s'attendent probablement à ce que vous demandiez si vous avez un pointeur sur le nœud principal. alors le pseudo-code est:

loop from head to end until test->next == curr 
test->next = curr->next; 
delete curr; 

Alternativement, si vous pouvez modifier la liste (sans le nœud principal):

temp = curr->next; 
curr->data = temp->data; 
curr->next = temp->next; 
delete temp; 
2

Je pense que c'est presque impossible dans les listes à lien unique si vous n'avez aucun pointeur vers la liste. Vous devriez toujours avoir un pointeur de tête de liste liée.

+0

Ok, dans le fil donné par codaddict dans le commentaire à la question il ya moyen de supprimer le noeud, si vous donnez comme argument c'est prédécesseur. –

+0

Alors que vous devriez avoir le pointeur de tête, il n'est pas impossible de supprimer un élément d'une liste unique sans lui (bien que techniquement vous copiez l'élément suivant sur l'élément suivant et en supprimant le suivant). Pour une liste doublement chaînée, il est trivial de supprimer sans pointeur de tête ou de queue. –

+0

C'est pourquoi j'ai écrit presque impossible et le commentaire. Comme vous avez remarqué cette méthode n'est pas vraiment la suppression du noeud. Si vous aviez quelque part un autre pointeur vers le nœud à côté de celui que vous avez "supprimé", vous obtiendrez des fautes de segmentation lorsque vous essaierez de faire quelque chose avec lui. Ce n'est pas acceptable pour moi. –

1

Dans une implémentation de liste chaînée standard, a pour modifier le noeud qui pointe vers le noeud en cours de suppression. Pour le modifier, vous devez le trouver en premier. Si vous avez un pointeur vers la tête de liste, ou un élément avant celui qui est supprimé, vous pouvez le trouver en parcourant la liste. Sinon, il n'y a pas de solution générale à ce problème. Vous pouvez sortir de la situation en modifiant la définition d'une liste liée pour marquer les nœuds supprimés (par exemple, avec un attribut booléen deleted), et à son tour modifier la traversée de la liste pour ignorer ces nœuds.

3

Eh bien, c'est juste un truc.

En supposant curr est l'adresse indiquée, suivant serait le code pseudo:

to_delete = curr->next 
curr->data = to_delete->data 
curr->next = to_delete->next 
delete to_delete 

essentiellement ces données seulement des copies et pointeur suivant du nœud suivant dans la liste au noeud courant et supprime le nœud suivant.

+0

Il semble que l'OP souhaite supprimer 'curr', pas' curr-> next'. Sinon, le problème est trop facile. ;) – AlcubierreDrive

+0

La même astuce peut être utilisée pour faire une insertion avant le nœud actuel, insérer un nœud après celui-ci et ensuite échanger les données; cependant les problèmes surgissent avec cette approche si quelqu'un d'autre tient un pointeur sur le noeud, il a été supprimé ou ses données ont changé! – Jackson

+0

J'ai moi-même fait face à cette question et je crois qu'il a réellement l'intention de supprimer la valeur et non le nœud lui-même :) (au moins c'était l'attente de moi). – mukeshkumar

1
You have a pointer to that node (say, node N). Meaning, you have access on that node. 
If that node has pointer to it's front node and it's back node, then simply point the back node to the front node. And the front node to the back of your node N. 

To illustrate: 
step 1: 
---> [ node ] ---> [ node ] ---> [ node ] ---> 
<--- [ M ] <--- [ N ] <--- [ O ] <--- etc... 

step 2: 
---> [ node ] -----------------> [ node ] ---> 
<--- [ M ] <--- [node N] <--- [ O ] <--- etc... 

step 3: 
---> [ node ] -----------------> [ node ] ---> 
<--- [ M ] <----------------- [ O ] <--- etc... 

            [ node ] ---> (still points to node O) 
     (still points to node M) <--- [ N ] 

step 4: 
just point Node N to NULL 
            [ node ] ---> NULL 
          NULL <--- [ N ] 

result: 
---> [ node ] -----------------> [ node ] ---> 
<--- [ M ] <----------------- [ O ] <--- etc... 
1

J'ai une solution si ce n'est pas la queue.

S'il s'agit d'une liste à liaison unique, il vous suffit de "permuter" avec le nœud à côté du vôtre et de supprimer celui-ci à la place.

En supposant que je

struct Node 
{ 
    T value; 
    Node * next; 
}; 

solution serait quelque chose comme:

void freeNode(Node * node) 
{ 
    Node * next = node->next; 
    if(next) 
    { 
     node->value = next->value; 
     node->next = next->next; 
     free(next); 
    } 
    // else I'm stuck! 
} 

Le genre de mélange ci-dessus pseudo de C et C++. Si le nœud que nous avons est la queue, et en supposant que la queue est indiquée par node-> next == NULL, je ne peux pas faire le nœud précédent dans la queue, donc je ne peux pas résoudre.