Comment mettre en place une liste liée dans C?
Je suis entrain de créer un liste liée comme dans la question précédente, j'ai demandé. J'ai trouvé que la meilleure façon de développer la liste chaînée est d'avoir la tête et la queue dans une autre structure. Mes produits struct sera imbriquée à l'intérieur de cette structure. Et je devrais être en train de passer la liste à la fonction d'ajout et de suppression. Je trouve ce concept confus.
J'ai mis en œuvre les initialiser, d'ajouter et de clean_up. Cependant, je ne suis pas sûr que je l'ai fait correctement.
Quand j'ajoute un produit à la liste, je déclare de la mémoire à l'aide de calloc. Mais je pense que je ne devrais pas être de déclarer la mémoire pour le produit à la place. Je suis vraiment confus au sujet de cet ajout.
Un grand merci pour toutes les suggestions,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PRODUCT_NAME_LEN 128
typedef struct product_data
{
int product_code;
char product_name[PRODUCT_NAME_LEN];
int product_cost;
struct product_data_t *next;
}product_data_t;
typedef struct list
{
product_data_t *head;
product_data_t *tail;
}list_t;
void add(list_t *list, int code, char name[], int cost);
void initialize(list_t *list);
void clean_up(list_t *list);
int main(void)
{
list_t *list = NULL;
initialize(list);
add(list, 10, "Dell Inspiron", 1500);
clean_up(list);
getchar();
return 0;
}
void add(list_t *list, int code, char name[], int cost)
{
//Allocate memory for the new product
list = calloc(1, sizeof(list_t));
if(!list)
{
fprintf(stderr, "Cannot allocated memory");
exit(1);
}
if(list)
{
//First item to add to the list
list->head->product_code = code;
list->head->product_cost = cost;
strncpy(list->head->product_name, name, sizeof(list->head->product_name));
//Terminate the string
list->head->product_name[127] = '/0';
}
}
//Initialize linked list
void initialize(list_t *list)
{
//Set list node to null
list = NULL;
list = NULL;
}
//Release all resources
void clean_up(list_t *list)
{
list_t *temp = NULL;
while(list)
{
temp = list->head;
list->head = list->head->next;
free(temp);
}
list = NULL;
list = NULL;
temp = NULL;
}
============================== Édité ============================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PRODUCT_NAME_LEN 64
//typedef struct product_data product_data_t;
typedef struct product_data
{
int product_code;
char product_name[PRODUCT_NAME_LEN];
int product_cost;
}product_data_t;
typedef struct list
{
struct list *head;
struct list *tail;
struct list *next;
struct list *current_node;
product_data_t *data;
}list_t;
void add(list_t *list, int code, char name[], int cost);
int main(void)
{
list_t *list = NULL;
list = initialize(list);
add(list, 1001, "Dell Inspiron 2.66", 1299);
add(list, 1002, "Macbook Pro 2.66", 1499);
clean_up(list);
getchar();
return 0;
}
void add(list_t *list, int code, char name[], int cost)
{
/* Allocate memory for the new product */
product_data_t *product = (product_data_t*) calloc(1, sizeof(*product));
if(!product)
{
fprintf(stderr, "Cannot allocate memory.");
exit(1);
}
/* This is the first item in the list */
product->product_code = code;
product->product_cost = cost;
strncpy(product->product_name, name, sizeof(product->product_name));
product->product_name[PRODUCT_NAME_LEN - 1] = '\0';
if(!list->head)
{
/* Assign the address of the product. */
list = (list_t*) product;
/* Set the head and tail to this product */
list->head = (list_t*) product;
list->tail = (list_t*) product;
}
else
{
/* Append to the tail of the list. */
list->tail->next = (list_t*) product;
list->tail = (list_t*) product;
}
/* Assign the address of the product to the data on the list. */
list->data = (list_t*) product;
}
- Est-il question ici?
- Le code de la initialize() est faux (tu avais seulement besoin d'au plus l'un des deux devoirs écrits, mais qui n'a aucun effet bénéfique); vous avez probablement censé liste->tete = NULL; liste->fin = NULL; et il y a un problème similaire dans clean_up().
- rendre cette un wiki de la communauté.
- connexes: codereview.stackexchange.com/questions/139482/...
Vous devez vous connecter pour publier un commentaire.
Dans votre cas, la tête et la queue pourrait pointez simplement le début et la fin d'une liste liée. Avec une seule liste liée, seule la tête est vraiment nécessaire. Il est plus de base, une liste liée peut être fait par l'utilisation d'une structure comme:
et aussi longtemps que la liste est toujours pointant vers le début de la liste et le dernier point a à côté de la valeur NULL, vous êtes fine et peut utiliser current_node la traversée de la liste. Mais parfois, pour faire en parcourant la liste plus facile et pour stocker d'autres données sur la liste, d'une tête et d'une queue de marque sont utilisés, et enveloppé dans leur propre structure, comme vous l'avez fait. Alors votre ajouter et d'initialiser des fonctions serait quelque chose comme (moins d'erreur de détection)
Dans ce cas, puisque c'est une seule liste liée, la queue n'est vraiment utile d'ajouter des éléments à la liste. Pour insérer un élément, vous devrez parcourir la liste, en commençant à la tête. Où la queue est vraiment pratique, c'est avec une liste à double liaison, il vous permet de parcourir la liste, en commençant à une des extrémités. Vous pouvez parcourir cette liste comme
Souvent, la tête et la queue sont entièrement construits les nœuds eux-mêmes utilisés comme une sentinelle pour indiquer le début et la fin d'une liste. Ils ne stockent pas les données elles-mêmes (bien plutôt, leurs données représentent une sentinelle jeton), ils sont juste les détenteurs de place pour l'avant et l'arrière. Cela peut rendre plus facile à coder des algorithmes traitant avec des listes liées à la charge d'avoir à disposer de deux éléments supplémentaires. Dans l'ensemble, les listes chaînées sont flexibles structures de données avec plusieurs façons de les mettre en œuvre.
oh ouais, et nik est à droite, en jouant avec les listes liées sont une excellente façon d'obtenir de bons avec les pointeurs et l'indirection. Et ils sont aussi un excellent moyen de pratiquer la récursivité trop! Après avoir obtenu de bons avec liste liée, essayez de construire un arbre à côté et à l'utilisation de la récursivité à pied de l'arbre.
Sans doute vous voulez que votre liste de données d'une structure externe pour les données qu'il stocke.
Dire que vous avez:
Alors votre structure de liste devrait ressembler à ceci:
Ryan Oberoi commenté de la même manière, mais w/o exemple.
Si vous êtes à la recherche afin de mieux comprendre les principes de base de listes liées, jetez un oeil au document suivant:
http://cslibrary.stanford.edu/103/LinkedListBasics.pdf
Je ne suis pas à écrire le code ici, mais vous devez faire ce qui suit:
Si vous êtes d'apprentissage C pointeur de la théorie, c'est un bon exercice.
Sinon, il se sent comme trop indirection pour le code qui n'est pas générique (comme dans une bibliothèque).
Au lieu de l'allocation statique de 128 octets chaîne de caractères, vous voulez peut-être faire plus de pointeur de la pratique et de l'utilisation d'un alloués exacte de la longueur de la chaîne que vous nettoyez jusqu'à la sortie.
Sur le plan scolaire,
kungfucraig
s' structure semble plus générique, puis celui que vous avez défini.Vous êtes calloc avec espace pour votre list_t struct, juste des pointeurs vers des liste la tête et la queue, ce qui n'est pas ce que vous voulez faire.
Lorsque vous ajoutez une liste liée, allouer de l'espace pour un nœud dans la liste, qui est votre product_data_t struct.
Vous êtes l'allocation de la mauvaise partie de la mémoire. Au lieu d'allouer de la mémoire pour chaque élément de la liste, vous êtes l'allocation pour la liste la tête et la queue.
Pour des raisons de simplicité, se débarrasser de la structure séparée pour la tête et la queue. Faire des variables globales (la même portée qu'ils sont dans l'instant) et de les changer pour être listhead et listtail. Cela permet de rendre le code plus lisible (vous ne serez pas inutilement en passant par une structure à part) et vous ne faites pas l'erreur de l'allocation pour le mauvais struct.
Vous n'avez pas besoin d'un indicateur de queue, sauf si vous allez faire une liste doublement chaînée. Ce n'est pas un élément majeur pour ajouter une fois que vous créez une liste liée, mais pas non plus indispensable.
Dans la mémoire de vos éléments sont reliés par des pointeurs dans la structure de la liste
item1 -> item2
Pourquoi ne pas en faire la liste de la structure de la partie de votre article?
Alors vous allouer un article de produit, et la structure de liste est en elle.
Je pense que u d'abord besoin de 'Imagin' back-end. Code ne sont rien d'important. Aller ici et de visualiser le back-end de base c le code de toutes les insertions.
1) Insertion à partir de Visitez et faites défiler jusqu'à obtenir toutes les instructions sur l'exécution de back - end
Et le besoin d'u avant et banque imagin rendez-vous ici
Back-end 'imagin'
Et Tous les autres d'insertion ici.
Et, plus important u peut utiliser de cette façon.
struct Noeud*tête,*de la queue; //essayez de cette façon
ou coupe courte
Et
<< Cliquez sur >> Pour voir d'autres liste liée problème.
Merci.
Une démo pour seule Liste Liée. Si vous préférez, essayez de vérifier Circulaire Liste Liée et Liste Doublement chaînée.
La liste liée de mise en œuvre inspirée par la mise en œuvre utilisé dans le noyau Linux:
Exemple d'utilisation:
Le résultat de l'exécution du code ci-dessus:
http://coliru.stacked-crooked.com/a/6e852a996fb42dc2
Bien sûr, dans la vraie vie, vous serez plus que probablement utiliser
malloc
pour les éléments de la liste.En langage C, nous avons besoin de définir un Nœud à stocker un nombre entier de données et un pointeur vers la valeur suivante.
Pour ajouter un nouveau nœud, nous avons une fonction add qui dispose de données comme un int en paramètre. Nous avons tout d'abord créer un nouveau Nœud n. Si le programme ne crée pas de n, puis on affiche un message d'erreur et retour avec la valeur -1. Si nous créons le n ensuite, nous avons défini les données de n de disposer des données du paramètre et la suivante contiendra la base, car il a le dessus de la pile. Après cela, nous avons défini la racine de la référence du nouveau nœud n.
C'est une manière simple de comprendre comment fonctionne le pointeur de travail avec le pointeur. Ici, vous devez simplement créer pointeur accroissement du nouveau nœud afin que nous puissions le rendre automatique.
return
à l'intérieur d'unfor
boucle.head->data
(ce qui n'est pas l'adresse de noeud, et si c'était l'incrémentation de la il serait de créer un pointeur non valide) et une seule itération de la boucle est exécuté parce que la boucle contientreturn 0;
. Regardez, la question a déjà été répondu en 2009, juste en rester là.Aller STL route. Déclarer les listes liées doivent être agnostique de données. Si vous avez vraiment l'écrire vous-même, jetez un oeil à la façon dont il est mis en œuvre dans la STL ou Boost.
Vous ne devriez même pas garder l' *suivant le pointeur de souris avec votre structure de données. Cela vous permet d'utiliser votre produit de la structure des données dans un divers nombre de structures de données - les arbres, les piles et les files d'attente.
Espère que cette info vous aide dans votre décision de conception.
Edit:
Depuis le poste est marqué C, vous avez l'équivalent implémentations utilisant void* pointeurs qui suivent le principe de conception de base. Pour un exemple, consultez:
La Documentation | liste.c | liste.h