#include "a_train.h" #include #include #include /// 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; }