DAS5102 - Listas Encadeadas
De Aulas
Voltar para DAS5102 Fundamentos da Estrutura da Informação
Exemplo
lista.c
1#include <stdlib.h>
2#include <string.h>
3#include <unistd.h>
4#include "list.h"
5
6void list_init(List *list, void (*destroy)(void *data))
7{
8 list->size = 0;
9 list->destroy = destroy;
10 list->head = NULL;
11 list->tail = NULL;
12 return;
13}
14
15void list_destroy(List *list)
16{
17 void *data;
18 while (list_size(list) > 0)
19 {
20 if (list_rem_next(list, NULL, (void **)&data) == 0 && list->destroy != NULL)
21 {
22 // Call a user-defined function to free dynamically allocated data.
23 list->destroy(data);
24 }
25 }
26 // clear the structure as a precaution
27 memset(list, 0, sizeof(List));
28 return;
29}
30
31int list_ins_next(List *list, ListElmt *element, const void *data)
32{
33 ListElmt *new_element;
34 if ((new_element = (ListElmt *) malloc(sizeof(ListElmt))) == NULL) return -1;
35 new_element->data = (void *) data;
36 if (element == NULL)
37 {
38 if (list_size(list) == 0)
39 list->tail = new_element;
40 new_element->next = list->head;
41 list->head = new_element;
42 }
43 else
44 {
45 if (element->next == NULL)
46 list->tail = new_element;
47 new_element->next = element->next;
48 element->next = new_element;
49 }
50 list->size++;
51 return 0;
52}
53
54int list_rem_next(List *list, ListElmt *element, void **data)
55{
56 ListElmt *old_element;
57 if (list_size(list) == 0) return -1;
58 if (element == NULL)
59 {
60 *data = list->head->data;
61 old_element = list->head;
62 list->head = list->head->next;
63 if (list_size(list) == 1) list->tail = NULL;
64 }
65 else
66 {
67 if (element->next == NULL) return -1;
68 *data = element->next->data;
69 old_element = element->next;
70 element->next = element->next->next;
71 if (element->next == NULL) list->tail = element;
72 }
73 free(old_element);
74 list->size--;
75 return 0;
76}
77
78void *list_dataN(List *list, int n)
79{
80 ListElmt *e = list->head;
81 int i;
82 for (i = 0; i < n; i++)
83 {
84 if (e == NULL) return NULL;
85 e = e->next;
86 }
87 return e->data;
88}
lista.h
1#ifndef LIST_H_INCLUDED
2#define LIST_H_INCLUDED
3
4typedef struct ListElmt_
5{
6 void *data;
7 struct ListElmt_ *next;
8} ListElmt;
9
10typedef struct List_
11{
12 int size;
13 int (*match)(const void *key1, const void *key2);
14 void (*destroy)(void *data);
15 ListElmt *head;
16 ListElmt *tail;
17} List;
18
19void list_init(List *list, void (*destroy)(void *data));
20
21void list_destroy(List *list);
22
23int list_ins_next(List *list, ListElmt *element, const void *data);
24
25int list_rem_next(List *list, ListElmt *element, void **data);
26
27void *list_dataN(List* list, int n);
28
29#define list_size(list) ((list)->size)
30
31#define list_head(list) ((list)->head)
32
33#define list_tail(list) ((list)->tail)
34
35#define list_is_head(list, element) ((element) == (list)->head ? 1 : 0)
36
37#define list_is_tail(element) ((element)->next == NULL ? 1 : 0)
38
39#define list_data(element) ((element)->data)
40
41#define list_next(element) ((element)->next)
42
43#endif // LIST_H_INCLUDED
main.c
1#include <stdio.h>
2#include <stdlib.h>
3#include "list.h"
4
5void destroy(void *data)
6{
7 free(data);
8 data = NULL;
9}
10
11int main()
12{
13 int i;
14 List *list = (List*) malloc(sizeof(List));
15 list_init(list, destroy);
16 for (i = 0; i < 5; i++)
17 {
18 int *data = malloc(sizeof(int));
19 *data = i;
20 printf("%d\n", *data);
21 list_ins_next(list, list->head, data);
22 }
23 int data = *((int*) list_dataN(list, 3));
24 printf("%d\n", data);
25 list_destroy(list);
26 return 0;
27}
Roteiro
1. Altere o TAD list.h e list.c vistos em aula para incluir a seguinte operação:
1void *list_dataN(List* list, int n);
Retornar os dados associados com o n-esimo elemento da lista, ou NULL caso a lista tenha menos que n elementos.
2. Faça um programa de teste que use list para testar a nova operação criada.