Last active
May 21, 2018 21:55
-
-
Save bbagno/2d3f4da634c47724b556fd55698d6645 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <errno.h> | |
#include <stddef.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include "linked_list.h" | |
// Создает ноду с указателем на data | |
node_t *construct_node(void *data) { | |
// Выделяем память под ноду | |
node_t *node = (node_t *)malloc(sizeof(node_t)); | |
// Если память не выделилась | |
if (!node) { | |
perror("Node memory allocation"); | |
exit(EXIT_FAILURE); | |
} | |
node -> data = data; | |
node -> next = NULL; | |
return node; | |
} | |
// Освобождает выделенную под ноду память | |
void destruct_node(node_t *node) { | |
free(node); | |
} | |
// Устанавливает ноду to_insert дочерней по отношению к dest | |
// Если у dest уже была дочерняя нода, она становится дочерней для to_insert вместо этого | |
void insert_after(node_t *to_insert, node_t *dest) { | |
to_insert -> next = dest -> next; | |
dest -> next = to_insert; | |
} | |
// Создает структуру с описанием односвязного списка | |
list_t *construct_list() { | |
// Выделяем память под структуру описания списка | |
list_t *list = (list_t *)malloc(sizeof(list_t)); | |
// Если не выделилось | |
if (!list) { | |
perror("List memory allocation"); | |
exit(EXIT_FAILURE); | |
} | |
list -> head = NULL; // говорим что начального элемента (ака голова) | |
list -> tail = NULL; // и конечного (ака хвост) | |
list -> size = 0; | |
return list; | |
} | |
// Освобождает память, занятую описанием списка и нодами | |
void destruct_list(list_t *list) { | |
// Сначала осовободлаем ноды | |
node_t *current_node, *next_node; | |
current_node = list -> head; | |
if (current_node) next_node = current_node -> next; | |
while (current_node) { | |
destruct_node(current_node); | |
current_node = next_node; | |
next_node = current_node -> next; | |
} | |
// А теперь и само описание списка | |
free(list); | |
} | |
void push(list_t *list, void *data) { | |
node_t *insert_node = construct_node(data); | |
if (list -> head) | |
insert_after(insert_node, list -> tail); | |
else | |
list -> head = insert_node; | |
list -> tail = insert_node; | |
list -> size += 1; | |
} | |
// Выполняет от каждой ноды списка list функцию lambda — см typedef void (*node_lambda)(node_t *node) | |
void each_node(list_t *list, node_lambda lambda) { | |
node_t *current_node = list -> head; | |
while (current_node) { | |
lambda(current_node); | |
current_node = current_node -> next; | |
} | |
} | |
// Выполняет от каждой ноды списка list и указателя на g функцию lambda | |
void each_node_gptr(list_t *list, node_global_pointer_lambda lambda, void *g) { | |
node_t *current_node = list -> head; | |
while (current_node) { | |
lambda(current_node, g); | |
current_node = current_node -> next; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef struct node { struct node *next; void *data; } node_t; | |
typedef void (*node_lambda)(node_t *node); | |
typedef void (*node_global_pointer_lambda)(node_t *node, void *global); | |
typedef struct linked_list { node_t *head; node_t *tail; int size; } list_t; | |
node_t *construct_node(void *data); | |
void destruct_node(node_t *node); | |
void insert_after(node_t *to_insert, node_t *dest); | |
list_t *construct_list(); | |
void destruct_list(list_t *list); | |
void push(list_t *list, void *data); | |
void each_node(list_t *list, node_lambda lambda); | |
void each_node_gptr(list_t *list, node_global_pointer_lambda lambda, void *g); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "linked_list.h" | |
// Функция, которая исходя из того, что в ноде хранится указатель на int | |
// печатает ноду | |
void print_node(node_t *node) { | |
printf("%d\n", *(int *)(node -> data)); | |
} | |
// Функция, которая исходя из того, что в ноде хранится указатель на int | |
// находит записывает в current_max MAX(current_max, значение из ноды) | |
void find_max(node_t *node, void *current_max) { | |
int node_val = *(int *)(node -> data); | |
int current_max_val = *(int *)current_max; | |
if (node_val > current_max_val) (*(int *)current_max) = node_val; | |
} | |
int main() { | |
// Объявляем два списка | |
list_t *list_1 = construct_list(); | |
list_t *list_2 = construct_list(); | |
// Объявляем массив чисел, позже запишем указатели на них в ноды наших списков | |
int array[] = { 3, 4, 3, 99, 4, 5, 18 }; | |
// Записываем массив в list_1 | |
for (int i = 0; i < 7; i++) push(list_1, array + i); | |
// Записываем массив в обратном порядке в list_2 | |
for (int i = 6; i >= 0; i--) push(list_2, array + i); | |
// Печатаем списки с помощью выполнения print_node для каждой ноды (each_node) | |
printf("list_1:\n"); | |
each_node(list_1, print_node); | |
printf("\nlist_2:\n"); | |
each_node(list_2, print_node); | |
// Находим максимальное значение в списке | |
int max = 0; | |
each_node_gptr(list_1, find_max, (void *)&max); | |
printf("\nmax: %d\n", max); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment