Skip to content

Instantly share code, notes, and snippets.

@bbagno
Last active May 21, 2018 21:55
Show Gist options
  • Save bbagno/2d3f4da634c47724b556fd55698d6645 to your computer and use it in GitHub Desktop.
Save bbagno/2d3f4da634c47724b556fd55698d6645 to your computer and use it in GitHub Desktop.
#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;
}
}
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);
#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