J'ai des problèmes avec ma méthode d'insertion pour une liste chaînée en C. Il semble ne faire qu'ajouter au début de la liste. Toute autre insertion que je fais échoue. Et ce débogueur CodeBlocks est si difficile à comprendre que je ne l’ai toujours pas compris. Cela ne me donne jamais de valeur, juste des adresses en mémoire. En tout cas c'est ma fonction. Voyez-vous une raison pour laquelle cela échoue?
/* function to add a new node at the end of the list */
int addNodeBottom(int val, node *head){
//create new node
node *newNode = (node*)malloc(sizeof(node));
if(newNode == NULL){
fprintf(stderr, "Unable to allocate memory for new node\n");
exit(-1);
}
newNode->value = val;
//check for first insertion
if(head->next == NULL){
head->next = newNode;
printf("added at beginning\n");
}
else
{
//else loop through the list and find the last
//node, insert next to it
node *current = head;
while(current->next != NULL)
{
if(current->next == NULL)
{
current->next = newNode;
printf("added later\n");
}
current = current->next;
}
}
return 0;
}
Ensuite, dans la partie principale, seul 929 est ajouté.
//testing addNodeBottom function
addNodeBottom(929, head);
addNodeBottom(98, head);
addNodeBottom(122, head);
addNodeBottom(11, head);
addNodeBottom(1034, head);
Ce code fonctionnera. La réponse de samplebias est presque correcte, mais vous avez besoin d'un troisième changement:
int addNodeBottom(int val, node *head){
//create new node
node *newNode = (node*)malloc(sizeof(node));
if(newNode == NULL){
fprintf(stderr, "Unable to allocate memory for new node\n");
exit(-1);
}
newNode->value = val;
newNode->next = NULL; // Change 1
//check for first insertion
if(head->next == NULL){
head->next = newNode;
printf("added at beginning\n");
}
else
{
//else loop through the list and find the last
//node, insert next to it
node *current = head;
while (true) { // Change 2
if(current->next == NULL)
{
current->next = newNode;
printf("added later\n");
break; // Change 3
}
current = current->next;
};
}
return 0;
}
Modification 1: newNode->next
doit être défini sur NULL
pour ne pas insérer de pointeurs non valides à la fin de la liste.
Changement 2/3: la boucle est changée en une boucle sans fin qui sera sautée avec break;
lorsque nous aurons trouvé le dernier élément. Notez comment while(current->next != NULL)
a contredit if(current->next == NULL)
avant.
EDIT: En ce qui concerne la boucle while, cette méthode est bien meilleure:
node *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
printf("added later\n");
Une fois que vous avez malloc
et node
, assurez-vous de définir node->next = NULL
.
int addNodeBottom(int val, node *head)
{
node *current = head;
node *newNode = (node *) malloc(sizeof(node));
if (newNode == NULL) {
printf("malloc failed\n");
exit(-1);
}
newNode->value = val;
newNode->next = NULL;
while (current->next) {
current = current->next;
}
current->next = newNode;
return 0;
}
Je dois préciser qu'avec cette version, la head
est toujours utilisée comme mannequin et non pour stocker une valeur. Cela vous permet de représenter une liste vide en ayant simplement un nœud head
.
Je voudrais mentionner la clé avant d’écrire le code pour votre considération.
//Clé
temp = adresse du nouveau noeud alloué par la fonction malloc (bibliothèque membre od alloc.h en C)
prev = adresse du dernier noeud de la liste de liens existante.
next = contient l'adresse du prochain noeud
struct node {
int data;
struct node *next;
} *head;
void addnode_end(int a) {
struct node *temp, *prev;
temp = (struct node*) malloc(sizeof(node));
if (temp == NULL) {
cout << "Not enough memory";
} else {
node->data = a;
node->next = NULL;
prev = head;
while (prev->next != NULL) {
prev = prev->next;
}
prev->next = temp;
}
}
Cela fonctionne bien:
struct node *addNode(node *head, int value) {
node *newNode = (node *) malloc(sizeof(node));
newNode->value = value;
newNode->next = NULL;
if (head == NULL) {
// Add at the beginning
head = newNode;
} else {
node *current = head;
while (current->next != NULL) {
current = current->next;
};
// Add at the end
current->next = newNode;
}
return head;
}
Exemple d'utilisation:
struct node *head = NULL;
for (int currentIndex = 1; currentIndex < 10; currentIndex++) {
head = addNode(head, currentIndex);
}
Le nouveau nœud est toujours ajouté après le dernier nœud de la liste liée donnée. Par exemple, si la liste chaînée donnée est 5-> 10-> 15-> 20-> 25 et que nous ajoutons un élément 30 à la fin, la liste chaînée devient 5-> 10-> 15-> 20-> 25- > 30 . Comme une liste chaînée est généralement représentée par son en-tête, nous devons parcourir la liste jusqu'à la fin, puis changer le prochain du dernier nœud en nouveau nœud.
/* Given a reference (pointer to pointer) to the head
of a list and an int, appends a new node at the end */
void append(struct node** head_ref, int new_data)
{
/* 1. allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
struct node *last = *head_ref; /* used in step 5*/
/* 2. put in the data */
new_node->data = new_data;
/* 3. This new node is going to be the last node, so make next
of it as NULL*/
new_node->next = NULL;
/* 4. If the <a href="#">Linked List</a> is empty, then make the new node as head */
if (*head_ref == NULL)
{
*head_ref = new_node;
return;
}
/* 5. Else traverse till the last node */
while (last->next != NULL)
last = last->next;
/* 6. Change the next of last node */
last->next = new_node;
return;
}