Lista jednokierunkowa zmiana typu danych

0

Mam napisaną w C listę jednokierunkową dla liczb całkowitych

 

#ifndef _LISTA_H_
#define _LISTA_H_


struct Node {
       int data;
       struct Node* next;
       };

int isEmpty(struct Node*);
void pushFront(struct Node**,int);
void pushBack(struct Node**,int);
int pop(struct Node**);

void insertNodeBefore(struct Node**,int,int);
void insertNodeAfter(struct Node** ,int ,int );
void deleteNode(struct Node**,int);
void deleteList(struct Node**);

void saveToFile(struct Node* head,char* path);
void loadFromFile(struct Node** head,char* path);

struct Node* findNode(struct Node*,int);
void reverse(struct Node**);
int size(struct Node*);
void printList(struct Node*);

void split(struct Node*,struct Node**,struct Node**);
void merge(struct Node**,struct Node*,struct Node*);
void mergesort(struct Node**);

#endif


 

#include<stdio.h>
#include<stdlib.h>
#include "lista.h"

 int isEmpty(struct Node* head)
 {
 return (head==NULL);
 }

 void pushFront(struct Node** head,int n)
 {
 struct Node* newNode;
 if((newNode=(struct Node*)malloc(sizeof(struct Node)))==NULL)
{
printf("Brak pamieci na wezel\n");
return;
 }
newNode->data=n;
newNode->next=(*head);
 (*head)=newNode;
 }

void pushBack(struct Node** head,int n)
 {
struct Node* newNode;
struct Node* temp;
 if((newNode=(struct Node*)malloc(sizeof(struct Node)))==NULL)
{
printf("Brak pamieci na wezel\n");
return;
}
 newNode->data=n;
 newNode->next=NULL;
if(isEmpty((*head)))
{
(*head)=newNode;
 }
else
{
 temp=(*head);
while(temp->next!=NULL)
temp=temp->next;
temp->next=newNode;
}
 }

 int pop(struct Node** head)
{
int val=0;
 struct Node* temp;
 if(!isEmpty((*head)))
{
 temp=(*head);
 val=temp->data;
(*head)=(*head)->next;
free(temp);
 }
 else printf("Struktura jest pusta\n");
return val;
}

void deleteNode(struct Node** head,int n)
{
struct Node* aux;
struct Node* previous;
if(isEmpty((*head)))
{
printf("Lista jest pusta\n");
}
else
{
aux=(*head);
previous=NULL;
while(aux!=NULL&&aux->data!=n){
previous=aux;
aux=aux->next;
}
if(aux==NULL){
printf("Liczby nie znaleziono na liscie\n");
}
else
{
if(previous==NULL)
{
(*head)=(*head)->next;
}
else
{
previous->next=aux->next;
}
free(aux);
}
}
}

void printList(struct Node* head)
{
struct Node* temp;
temp=head;
while(temp!=NULL)
{
printf("%d\n",temp->data);
temp=temp->next;
}
}

void deleteList(struct Node** head)
{
    while(!isEmpty((*head)))
    {
        deleteNode(head,(*head)->data);
    }
}

struct Node* findNode(struct Node* head,int n)
{
 struct Node* temp;
 temp=head;
 while(temp!=NULL&&temp->data!=n)
    temp=temp->next;
 return temp;
}

void insertNodeBefore(struct Node** head,int x1,int x2)
{
    struct Node* newNode;
    struct Node* save;
    struct Node* pred;

    if((newNode=(struct Node*)malloc(sizeof(struct Node)))==NULL)
    {
        printf("Brak pamieci na wezel\n");
    }
    newNode->data=x2;
    if((*head)==NULL)
    {
        printf("Wezla nie znaleziono \n");
    }
    else
    {
        save=(*head);
        while(x1!=save->data&&save->next!=NULL)
        {
            pred=save;
            save=save->next;
        }
        if(save->data==x1)
        {
            if((*head)==save)
            {
                newNode->next=save;
                (*head)=newNode;
            }
            else
            {
                newNode->next=save;
                pred->next=newNode;
            }
        }
        else
        {
            printf("Wezla nie znaleziono\n");
        }
    }

}

void insertNodeAfter(struct Node** head,int x1,int x2)
{
    struct Node* newNode;
    struct Node* save;
    struct Node* pred;

    if((newNode=(struct Node*)malloc(sizeof(struct Node)))==NULL)
    {
        printf("Brak pamieci na wezel\n");
        return;
    }
    newNode->data=x2;
    if((*head)==NULL)
    {
        printf("Wezla nie znaleziono\n");
    }
    else
    {
        save=(*head);
        while((x1!=save->data)&&(save->next!=NULL))
        {
            pred=save;
            save=save->next;
        }
        if(save->data==x1)
        {
            newNode->next=save->next;
            save->next=newNode;
        }
        else
            {
            printf("Wezla nie znaleziono\n");
        }
    }
}

void reverse(struct Node ** head)
{
    struct Node * prev=NULL;
    struct Node * current=(*head);
    struct Node * next=NULL;

    while(current!=NULL)
    {
        next=current->next;
        current->next=prev;
        prev=current;
        current=next;
    }
    (*head)=prev;
}

void saveToFile(struct Node* head,char* path)
{
    FILE* fp;
    struct Node* temp;

    if ((fp = fopen(path, "wt"))
       == NULL)
   {
      fprintf(stderr, "Cannot open output file.\n");
      return ;
   }
   temp=head;
   while(temp!=NULL)
   {
       fprintf(fp,"%d\n",temp->data);
       temp=temp->next;
   }
   fclose(fp);

}
void loadFromFile(struct Node** head,char* path)
{
    FILE* fp;
    int value;
    if ((fp = fopen(path, "rt"))
       == NULL)
   {
      fprintf(stderr, "Cannot open input file.\n");
      return ;
   }
   while(!feof(fp))
   {
     fscanf(fp,"%d",&value);
     pushFront(head,value);
   }
   fclose(fp);
}


int size(struct Node* head)
{
    int no=0;
    struct Node* temp;
    temp=head;
    while(temp!=NULL)
    {
        no++;
        temp=temp->next;
    }
    return no;
}

    void split(struct Node* head,struct Node** front,struct Node** back)
    {
    struct Node* slow;
    struct Node* fast;
    if(head==NULL||head->next==NULL)
    {
    (*front)=head;
    (*back)=NULL;
    }
    else
    {
    slow=head;
    fast=head->next;

    while(fast!=NULL)
    {
    fast=fast->next;
    if(fast!=NULL)
    {
    slow=slow->next;
    fast=fast->next;
    }
    }
    (*front)=head;
    (*back)=slow->next;
    slow->next=NULL;
    }
    }

    void merge(struct Node** head,struct Node* list1,struct Node* list2)
    {
    struct Node* tmp;
    if(list1==NULL) (*head)=list2;
    if (list2==NULL) (*head)=list1;
     if(list1->data<=list2->data)
     {
     (*head)=list1;
     }else{
     (*head)=list2;
     list2=list1;
     list1=(*head);
     }
     while((list1->next!=NULL)&&(list2!=NULL))
     {
     if(list1->next->data<=list2->data){
     list1=list1->next;
     }else{
     tmp=list1->next;
     list1->next=list2;
     list2=tmp;
     }
    }
    if(list1->next==NULL) list1->next=list2;
    }

    void mergesort(struct Node** head)
    {
    struct Node* h1=NULL;
    struct Node* h2=NULL;
    if((*head)!=NULL&&(*head)->next!=NULL)
    {
    split((*head),&h1,&h2);
    mergesort(&h1);
    mergesort(&h2);
    merge(head,h1,h2);
    }
    }



Co zmienić aby typem danych był void*

Na jednej stronie koleś napisał że
trzeba indywidualnie zaprogramować kilka funkcji operujących na strukturze danych

2

No skoro to napisałeś to chyba lepiej wiesz co się dzieje w kodzie niż ktokolwiek.
No a jeżeli ty tego nie napisałeś to go zrozum.

0

Kiedyś popełniłem coś takiego bawiąc się uzyskaniem generyka w C:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct node{
    void *value;
    struct node *next;
    struct node *previous;
};

struct person{
    char name[10];
    char surname[10];
};

struct car{
    char model[15];
};

void add(struct node** list, void* value){
    struct node* newNode = (struct node*)malloc(sizeof(struct node));
    newNode->value = value;
    newNode->previous = NULL;
    newNode->next = (*list);
    if(*list) (*list)->previous = newNode;
    (*list) = newNode;
}

void erase(struct node **list){
    struct node *temp = (*list);
    while(temp){
        struct node* next = temp->next;
        free(temp->value);
        free(temp);
        temp = next;
    }
}

int main(){
    struct node *list = NULL;
    struct person *first = (struct person*)malloc(sizeof(struct person));
    strcpy(first->name, "Thomas");
    strcpy(first->surname, "Anderson");

    struct car *second = (struct car*)malloc(sizeof(struct car));
    strcpy(second->model, "Mercedes");

    add(&list,first);
    add(&list,second);

    erase(&list);
    return 0;
}

Już mi się nie chce print'a pisać więc masz screena z debuga na dowód, że to działa:
33f8156676.png

==10549== Memcheck, a memory error detector
==10549== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==10549== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==10549== Command: ./Programy_C
==10549== 
==10549== 
==10549== HEAP SUMMARY:
==10549==     in use at exit: 0 bytes in 0 blocks
==10549==   total heap usage: 4 allocs, 4 frees, 59 bytes allocated
==10549== 
==10549== All heap blocks were freed -- no leaks are possible
==10549== 
==10549== For counts of detected and suppressed errors, rerun with: -v
==10549== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Resztę przerób sobie samemu.

0
void add(struct node** list, void* value){
    struct node* newNode = (struct node*)malloc(sizeof(struct node));
    newNode->value = value;
    newNode->previous = NULL;
    newNode->next = (*list);
    if(*list) (*list)->previous = newNode;
    (*list) = newNode;
}
0

Jeśli chodzi o zapis i odczyt do/z pliku to
lepiej jako parametr funkcji dać wskaźnik na strukturę plikową czy ścieżkę do pliku

0

Tak na dobrą sprawę to chciałem przystosować tą listę do zabawy z plikami
Jeśli chodzi o dane to mielibyśmy dwa pola
int - numer linii
char* treść linii
przy czym polem kluczowym byłoby pole char*
Wprowadzenie listy miało zminimalizować liczbę odczytu z dysku

Podanie jako typu danych void* też wydaje mi się dobrym rozwiązaniem

Tak napisana lista może mi się przydać jedynie do przesiewania liczb złożonych
czy po odpowiedniej modyfikacji do problemu Flawiusza

0

Do Flawiusza zwykła tablica bardziej pasuje, nie wiem czym jest "przesiewanie liczb złożonych" ale podejrzewam ze też lepsza tablica będzie.

0

Masz pseudogeneryka z jedną gwiazdką (o to cała dyskusja chyba była):

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct node{
    void *value;
    unsigned index;
    struct node *next;
}node;

typedef struct{
    unsigned count;
    node *head;
}list;

typedef struct{
    char name[15];
}car;

typedef struct{
    char name[10];
    char surname[20];
}person;

void add(list *list, void *value){
    node* newNode = (node*)malloc(sizeof(node));
    newNode->value = value;
    newNode->next = list->head;
    newNode->index = list->count;

    list->head = newNode;
    list->count += 1;
}

void* get(list *list, unsigned index){
    node* temp;
    for(temp = list->head; temp != NULL; temp = temp->next)
        if(temp->index == index) return temp->value;
    return NULL;
}

void erase(list *list){
    while(list->head){
        node *next = list->head->next;
        free(list->head->value);
        free(list->head);
        list->head = next;
    }
}

void printPerson(const person* person){
    printf("Selected Person:\nName: %s\nSurname: %s\n", person->name, person->surname);
}

void printCar(const car* car){
    printf("Selected Car:\nName: %s\n", car->name);
}

int main(){
    list list = { 0, NULL };
    car *cars[] = { (car*)malloc(sizeof(car)), (car*)malloc(sizeof(car)) };
    strcpy(cars[0]->name, "Mercedes");
    strcpy(cars[1]->name, "Audi");

    person *persons[] = { (person*)malloc(sizeof(person)), (person*)malloc(sizeof(person)) };
    strcpy(persons[0]->name, "Grzegorz");
    strcpy(persons[0]->surname, "Igrekowski");
    strcpy(persons[1]->name, "Karolina");
    strcpy(persons[1]->surname, "Iksinska");

    unsigned i = 0;
    for(; i < sizeof(cars) / sizeof(cars[0]); ++i) add(&list, cars[i]);
    for(i = 0; i < sizeof(persons) / sizeof(persons[0]); ++i) add(&list, persons[i]);

    printCar((car*)get(&list, 0));
    printPerson((person*)get(&list, 2));
    erase(&list);

    return 0;
}

http://ideone.com/WQ3Msk
Resztę dopisz sobie samemu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1