-
Notifications
You must be signed in to change notification settings - Fork 1
Implementando uma linked list genérica que aceita dados de qualquer … #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| CC = gcc | ||
| CFLAGS = -Wall | ||
| LDFLAGS = | ||
| OBJFILES = primitive_types_functions.o genericLL.o main.o | ||
| TARGET = main | ||
|
|
||
| all: $(TARGET) | ||
|
|
||
| $(TARGET): $(OBJFILES) | ||
| $(CC) $(CFLAGS) -o $(TARGET) $(OBJFILES) $(LDFLAGS) | ||
| clean: | ||
| rm -f $(OBJFILES) $(TARGET) *~ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| #include <stdlib.h> | ||
| #include <stdio.h> | ||
| #include "genericLL.h" | ||
|
|
||
| void push(Node **head, void *val, size_t data_size) | ||
| { | ||
| Node *new_node = (Node *)malloc(sizeof(Node)); | ||
|
|
||
| new_node->data = malloc(data_size); | ||
| /*como char tem um byte copia byte por byte*/ | ||
| for (int i = 0; i < data_size; i++) | ||
| *(char *)(new_node->data + i) = *(char *)(val + i); | ||
|
|
||
| new_node->next = NULL; | ||
| if (*head == NULL) | ||
| { | ||
| *head = new_node; | ||
| return; | ||
| } | ||
| Node *p = *head; | ||
| while (p->next != NULL) | ||
| p = p->next; | ||
|
|
||
| p->next = new_node; | ||
| return; | ||
| } | ||
|
|
||
| /*Como a lista é genérica, ou seja, pode ter qualquer tipo de data type, passamos uma função específica para o data type que está sendo usado | ||
| para comparar os elementos.*/ | ||
| void delete (Node **head, void *val, int (*compare)(void *, void *)) | ||
| { | ||
| if (*head == NULL) | ||
| return; | ||
|
|
||
| Node *p = *head; | ||
| Node *ant = NULL; | ||
|
|
||
| if (p->next == NULL && (*compare)(p->data, val) == 0) | ||
| { | ||
| *head = NULL; | ||
| return; | ||
| } | ||
|
|
||
| while (p->next != NULL) | ||
| { | ||
| int comp = (*compare)(p->data, val); | ||
| if (comp == 0) | ||
| { | ||
|
|
||
| if (ant == NULL) | ||
| { | ||
| *head = p->next; | ||
| free(p->data); | ||
| return; | ||
| } | ||
| else | ||
| { | ||
| ant->next = p->next; | ||
| free(p->data); | ||
| } | ||
| } | ||
| ant = p; | ||
| p = p->next; | ||
| } | ||
| } | ||
| /*Essa função vai apenas percorrer a lista e passar cada elemento para uma função | ||
| recebida como parâmetro que printa especificamente aquele data type. */ | ||
| void printList(Node *head, void (*printData)(void *)) | ||
| { | ||
| Node *p = head; | ||
| while (p) | ||
| { | ||
| (*printData)(p->data); | ||
| p = p->next; | ||
| } | ||
| puts(""); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| typedef struct Node | ||
| { | ||
| void *data; | ||
| struct Node *next; | ||
| } Node; | ||
|
|
||
| void push(Node **head, void *val, size_t size); | ||
| void delete (Node **head, void *val, int (*compare)(void *, void *)); | ||
| void printList(Node *head, void (*printData)(void *)); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
| #include "genericLL.h" | ||
|
|
||
| /*print e compare para char, int, float, double and string*/ | ||
| #include "primitive_types_functions.h" | ||
|
|
||
| int main() | ||
| { | ||
| Node *integers = NULL; | ||
| Node *floats = NULL; | ||
| Node *chars = NULL; | ||
| Node *strings = NULL; | ||
|
|
||
| char char_arguments[10] = {97, 98, 99, 100, 101, 102, 103, 104, 105, 106}; | ||
| for (int i = 0; i < 10; i++) | ||
| push(&chars, &char_arguments[i], sizeof(char_arguments[i])); | ||
| printList(chars, printChar); | ||
| for (int i = 0; i < 10; i++) | ||
| { | ||
| printf("Após tirar o %c: ", char_arguments[i]); | ||
| delete (&chars, &char_arguments[i], compareChar); | ||
| printList(chars, printChar); | ||
| } | ||
|
|
||
| int arguments[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; | ||
| for (int i = 0; i < 10; i++) | ||
| push(&integers, &arguments[i], sizeof(arguments[i])); | ||
| printList(integers, printInt); | ||
| for (int i = 0; i < 10; i++) | ||
| { | ||
| printf("Após tirar o %d: ", arguments[i]); | ||
| delete (&integers, &arguments[i], compareInt); | ||
| printList(integers, printInt); | ||
| } | ||
|
|
||
| float float_arguments[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; | ||
| for (int i = 0; i < 10; i++) | ||
| push(&floats, &float_arguments[i], sizeof(float_arguments[i])); | ||
| printList(floats, printFloat); | ||
| for (int i = 0; i < 10; i++) | ||
| { | ||
| printf("Após tirar o %f: ", float_arguments[i]); | ||
| delete (&floats, &float_arguments[i], compareFloat); | ||
| printList(floats, printFloat); | ||
| } | ||
|
|
||
| char strings_arguments[10][20] = | ||
| { | ||
| "Casa", "cavalo", "carteira", "fidedigno", "nasogástrico", | ||
| "hipopótamo", "malabarista", "JBL", "React-native", "Swift"}; | ||
|
|
||
| for (int i = 0; i < 10; i++) | ||
| push(&strings, &strings_arguments[i], sizeof(strings_arguments[i])); | ||
| printList(strings, printString); | ||
| for (int i = 0; i < 10; i++) | ||
| { | ||
| printf("Após tirar o %s: ", strings_arguments[i]); | ||
| delete (&strings, &strings_arguments[i], compareStrings); | ||
| printList(strings, printString); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| #include <stdio.h> | ||
| #include <string.h> | ||
| #include "primitive_types_functions.h" | ||
|
|
||
| void printChar(void *data) | ||
| { | ||
| printf("%c ", *(char *)data); | ||
| } | ||
|
|
||
| void printInt(void *data) | ||
| { | ||
| printf("%d ", *(int *)data); | ||
| } | ||
|
|
||
| void printFloat(void *data) | ||
| { | ||
| printf("%f ", *(float *)data); | ||
| } | ||
|
|
||
| void printDouble(void *data) | ||
| { | ||
| printf("%lf ", *(double *)data); | ||
| } | ||
|
|
||
| void printString(void *data) | ||
| { | ||
| printf("%s ", (char *)data); | ||
| } | ||
|
|
||
| int compareChar(void *a, void *b) | ||
| { | ||
| char num1 = *(char *)a; | ||
| char num2 = *(char *)b; | ||
| if (num1 > num2) | ||
| return 1; | ||
| if (num1 == num2) | ||
| return 0; | ||
| return -1; | ||
| } | ||
|
|
||
| int compareInt(void *a, void *b) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same about the return documentation for all methods that this applies |
||
| { | ||
| int num1 = *(int *)a; | ||
| int num2 = *(int *)b; | ||
| if (num1 > num2) | ||
| return 1; | ||
| if (num1 == num2) | ||
| return 0; | ||
| return -1; | ||
| } | ||
|
|
||
| int compareFloat(void *a, void *b) | ||
| { | ||
| float precision = 0.000001; | ||
| float num1 = *(float *)a; | ||
| float num2 = *(float *)b; | ||
|
|
||
| float aux = num1 - num2; | ||
| if (aux > precision) | ||
| return 1; | ||
| if (aux <= precision && aux > precision * -1.0) | ||
| return 0; | ||
| return -1; | ||
| } | ||
|
|
||
| int compareDouble(void *a, void *b) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think about using the |
||
| { | ||
| double precision = 0.000001; | ||
| double num1 = *(double *)a; | ||
| double num2 = *(double *)b; | ||
|
|
||
| double aux = num1 - num2; | ||
| if (aux > precision) | ||
| return 1; | ||
| if (aux <= precision && aux > precision * -1.0) | ||
| return 0; | ||
| return -1; | ||
| } | ||
|
|
||
| int compareStrings(void *a, void *b) | ||
| { | ||
|
|
||
| return (strcmp((char *)a, (char *)b)); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
|
|
||
|
|
||
| void printChar(void *data); | ||
|
|
||
| void printInt(void *data); | ||
|
|
||
| void printFloat(void *data); | ||
|
|
||
| void printDouble(void *data); | ||
|
|
||
| void printString(void *data); | ||
|
|
||
| int compareChar(void *a, void *b); | ||
|
|
||
| int compareInt(void *a, void *b); | ||
|
|
||
| int compareFloat(void *a, void *b); | ||
|
|
||
| int compareDouble(void *a, void *b); | ||
|
|
||
| int compareStrings(void *a, void *b); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider documenting what each return parameter means, e.g.
0 -> they are equal
1 and -1 > greater or lower
One option is using the
@paramtag