usaa25/du4/a_train.c

132 lines
4.5 KiB
C

#include "a_train.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/// funkcia na pridanie noveho nodu do linked lista
struct car* add_car(struct car* first,const char* target) {
//ak prvy nod je NULL, tak pridame novy nod na zaciatok
if(first == NULL){
// calloc dynamicke allokuje pamat a initicializuje byty a niceo - 1 v danom pripade
first = calloc(1, sizeof(struct car));
//prekorpirovanie zadaneho ret'azca target v hodnotu noda
strcpy(first->value, target);
// vratime prvy nod
return first;
}
// pomocny nod pre prechadzanie zoznamu
struct car* temp = first;
// prechadzame pokial' mozeme, cize pokial' next nie je NULL
while(temp->next){
// zmenime aktualny pointer na nasledujuci nod v zozname
temp = temp->next;
}
// Ak sme vysle z cyklusu, tak to znamena ze sme na konci zoznamu a mozeme pridat' na koniec novy uzol
struct car* newCar = (struct car*)calloc(1, sizeof(struct car));
strcpy(newCar->value, target);
// temp je pointer na posledny uzol, preto pridame vytvoreny na koniec ako net posledneho uzla
temp->next = newCar;
// vratime hlavu zoznamu
return first;
}
// funkcia pre vypis vsetkych uzlov v zozname
void print_train(struct car* first) {
// pomocny pointer na prvy uzol
struct car* temp = first;
// pokial node nie je NULL, mozeme vypisa't ho hodnotu a prejdeme d'alej
while(temp){
printf("%s\n", temp->value);
// prechadzame zoznam
temp = temp->next;
}
}
// funkcia pre vymazanie zoznamu
// recursivna implementacia
void cancel_train(struct car* first) {
// ked' prvy uzol je NULL, tak neurobime nic a zrusime program
if(first == NULL){
return;
}
// volame funkciu na na nasledujuci node
// to znamena, ze prvy uzol bude uvolneny z pamati poslednim
cancel_train(first->next);
// uvolnime z pamati uzol
free(first);
}
// funkcia pre vymazanie vsetkych zlov z urcitou hodnotou
struct car* clear_train(struct car* first, const char* target) {
// Ak hlava je NULL, tak vratime NULL
if(first == NULL){
return NULL;
}
/// Ak v zozname len jeden uzol a zol ma hodnotu zhodnotu s target, tak vymazeme ho a vuvolnyme pamat
if (first->next == NULL && strcmp(first->value, target) == 0)
{ // uvolnyme pamat a vratime NULL
free(first);
return NULL;
}
// ak nie, tak vratime uzol
else if(first->next == NULL && strcmp(first->value, target) != 0){
return first;
}
/// ak mame dva uzly v zozname, kde hlava ma prislusnu hodnotu
if(first->next->next == NULL && strcmp(first->value, target) == 0){
// pomocny pointer pre uvolnenie pamati
struct car* temp = first;
// teraz nova hlava bude nasledujuci uzol
first = first->next;
// nasledujuci uzol novej hlavy bude NULL, pretoze mame len dva uzly
first->next = NULL;
// uvolnyme v pamati pomocny pointer, respektive hlavu z hodnotou target
free(temp);
// vratime novy zacatok
return first;
}
// cyklus while pre vymazanie vsetkych nodov z hodnotou target na zaciatku ak mame 3 a vel'a nodov
while(first!= NULL & strcmp(first->value, target) == 0){
// pomocny node pre vymazanie
struct car* targetNode = first;
// posuneme d'alej zaciatok a uvolnyme v pamati hlavu
first = first->next;
free(targetNode);
}
// pomocne pointery pre prechadzanie a porovnanie
// pointer na predchadzajuci node
struct car* prev= first;
// pointer na nasledujuci node
struct car* temp = first->next;
// pokial aktulany (predchadzajuci) a nasledujuci nie su NULL
/// prechadzame zoznamom
while (prev && temp)
{ // ak nasledujuci ma hodnotu rovnaku ako target
if(strcmp(temp->value, target) == 0){
// pomocny pointer pre vymazanie a preradenie
struct car* targetNode = temp;
// preriadime link next aktualneho pointera na temp->next, cize na next->next
prev->next = temp->next;
// preriadime nasledujuci na node, ktory ide po nho, respektive na next->next
temp = temp->next;
//uvolnime v pamati prsilusny uzol
free(targetNode);
}
// ak nezhoduju hodnoty, tak pokracujeme v iteracii
else{
// posuneme aktualny na nasledujuci
prev = temp;
// tak tiez preriademe nasledujuci d'alej
temp = temp->next;
}
}
// vratime hlavu
return first;
}