Split list double chained with head

1

I'm having a problem with the Divide function, where I'm getting a list and want to return the right part and the left part of the list. Can someone give me some help with logic.

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

struct celula {
    int num;
    struct celula * seg;
    struct celula * ant;
};

typedef struct celula Numero;



int gerarNumeros(int n);
int numeroDigitos(Numero * lst);
void geraSeed();
void geraLista(Numero *lst, int numeros);
void insereLista(Numero *lst, int num);
void imprimeLista(Numero * lst);
Numero * criaLista(int n);
Numero * DivideDireita(Numero *a, int n);


int main() {
    Numero * head_n1, * head_n2, * resposta ,* head1 ;
    int d;


    printf("Insira a quantidade de DIGITOS do seu numero binario\n");
    scanf("%i", &d);

    head_n1 = criaLista(1); 
    head_n2 = criaLista(1);
    head1 = criaLista(1);
    head2 = criaLista(1);
    printf("Criando os dois numeros... \n\n");

    geraLista(head_n1, d);
    geraLista(head_n2, d);

    imprimeLista(head_n1);

    printf("\n\n\n");

    head1 = DivideDireita(head_n1, d/2);
  //head2 = DivideEsquerda(head_n1,d/2);

    printf("\n Parte 1");
    printf("\n");
    imprimeLista(head1);  


    printf("\n Parte 2");

    printf("\n");
    //imprimeLista(head2);     
    printf("\n");
    getchar();

    return 0;

}


Numero * DivideDireita(Numero *a, int n)
 {
   Numero * novo;
   Numero * aux;
   aux= a->ant;
   novo = criaLista(1);

for(int i=0; i<n; i++)
{

    insereLista(novo,aux->num);
    aux = aux->ant;
}

return novo;
}


/*Retorna um numero com outro endereço*/

Numero * copia(Numero * a)
{

    Numero * nova, * aux;

    aux = a->ant;
    nova = criaLista(a->num); // cria nova cabeça igual a cabeça de a

    while(aux != a) { // percorre do final até o começo
        insereLista(nova, aux->num);
        aux = aux->ant;
    }
    return aux; // devolve a cabeça do numero copiado
}



int numeroDigitos(Numero * lst)
{
    Numero * aux;
    int i;

    i = 0;
    aux = lst->seg;
    while(aux != lst) {
        aux = aux->seg;
        i++;
    }
    return i;
}

/*Retorna um ponteiro para uma copia do numero*/
Numero *copiaNum(Numero *head) 
{
    Numero *aux = head->ant;
    Numero *copia = criaLista(0);
    while(aux != head){
        insereLista(copia, aux->num);
        aux = aux->ant;
    }
    return copia;
}



/*Gerar numeros entre 0 ou 1 se n=2*/
int gerarNumeros(int n){
    return rand() % n ;
}

void geraSeed() { /* gera uma seed para nova sequencia de numeros aleatorios */
    srand((unsigned)time(NULL));
}





void removeNumero(Numero * rm) { // desaloca a memória da célula indicada
    Numero * aux;

    if(rm->seg == rm) { // se a celula for a cabeça
        free(rm); // desaloca rm
    } else { 
        aux = rm->ant;
        aux->ant->seg = rm;
        rm->ant = aux->ant;
        free(aux); // desaloca aux
    }
}


void insereLista(Numero *lst, int num)
{
    Numero *novo;
    novo = (Numero*) malloc(sizeof(Numero));
    novo->num = num; //acessa nova e bota o endereço da pessoa1 lá dentro;

    if(lst->seg == lst) {
        novo->seg = lst;
        lst->seg = novo;
        novo->ant = lst;
        lst->ant = novo;
        return;
    }
    novo->seg = lst->seg;
    lst->seg = novo;
    novo->seg->ant = novo;
    novo->ant = lst;
}

void geraLista(Numero *numero, int numeros) 
{
    int i;
    i=0;
    while (i != numeros) { // deve ser colocado 256 digitos
        insereLista(numero, gerarNumeros(2)); //GERANDO NUMEROS DE 0-1 E GUARDANDO NA LISTA
        i++;
    }
}
/*Cria uma lista*/
Numero * criaLista(int n)
{
    Numero * head;
    head = (Numero *) malloc(sizeof(Numero));
    head->num = n;
    head->seg = head;
    return head;

}

/*Imprime a lista caso o primeiro numero tenha um -1 é porque*/
/*o numero é negativo                                        */
void  imprimeLista(Numero * lst)
{
    //int i;
    Numero * aux;
    aux = lst->seg;
    //i=0;
    /*Imprimir o sinal*/
    if(lst->num == -1)  {
        printf("-");
    }

    while(aux != lst)
    {
        printf("%i", aux->num);
        aux = aux->seg;
        //i++;

    }


}

EDIT CODE ... List for left is returning the opposite, I thought to make one inserts at the end of the list because the function that I implemented is inserting at the beginning, I am wanting to optimize this without having to create a new function.

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

struct celula {
    int num;
    struct celula * seg;
    struct celula * ant;
};

typedef struct celula Numero;



int gerarNumeros(int n);
int numeroDigitos(Numero * lst);
void geraSeed();
void geraLista(Numero *lst, int numeros);
void insereLista(Numero *lst, int num);
void imprimeLista(Numero * lst);
Numero * criaLista(int n);
Numero * DivideEsquerda(Numero *a, int n);
Numero * DivideDireita(Numero *a, int n);


int main() {
    Numero * head_n1, * head_n2, * resposta , *head1, *head2 ;
    int d;


    printf("Insira a quantidade de DIGITOS do seu numero binario\n");
    scanf("%i", &d);

    head_n1 = criaLista(1); 
    head_n2 = criaLista(1);
    head1 = criaLista(1);
    head2 = criaLista(1);
    printf("Criando os dois numeros... \n\n");

    geraLista(head_n1, d);
    geraLista(head_n2, d);

    imprimeLista(head_n1);

    printf("\n\n\n");

    head1 = DivideEsquerda(head_n1, d/2);
    head2 = DivideDireita(head_n1, d/2);

    printf("\n Parte 1");
    printf("\n");
    imprimeLista(head1);  

    printf("\n Parte 2");

    printf("\n");
    imprimeLista(head2);     
    printf("\n");
    getchar();

    return 0;

}


Numero * DivideEsquerda(Numero *a, int n)
{
Numero * esq;
Numero * aux;
aux= a->seg;
esq = criaLista(1);

for(int i=n; i>0; i--)
{
    insereListaFim(esq,aux->num);
    aux = aux->seg;

}
return esq;
}

Numero * DivideDireita(Numero *a, int n){
Numero * dir;
Numero * aux;
aux= a->ant;
dir = criaLista(1);

for(int i=0; i<n; i++)
{

    insereLista(dir,aux->num);
    aux = aux->ant;

}
return dir;
}

/*Retorna um numero com outro endereço*/

Numero * copia(Numero * a)
{

    Numero * nova, * aux;

    aux = a->ant;
    nova = criaLista(a->num); // cria nova cabeça igual a cabeça de a

    while(aux != a) { // percorre do final até o começo
        insereLista(nova, aux->num);
        aux = aux->ant;
    }
    return aux; // devolve a cabeça do numero copiado
}



int numeroDigitos(Numero * lst)
{
    Numero * aux;
    int i;

    i = 0;
    aux = lst->seg;
    while(aux != lst) {
        aux = aux->seg;
        i++;
    }
    return i;
}

/*Retorna um ponteiro para uma copia do numero*/
Numero *copiaNum(Numero *head) 
{
    Numero *aux = head->ant;
    Numero *copia = criaLista(0);
    while(aux != head){
        insereLista(copia, aux->num);
        aux = aux->ant;
    }
    return copia;
}



/*Gerar numeros entre 0 ou 1 se n=2*/
int gerarNumeros(int n){
    return rand() % n ;
}

void geraSeed() { /* gera uma seed para nova sequencia de numeros aleatorios */
    srand((unsigned)time(NULL));
}





void removeNumero(Numero * rm) { // desaloca a memória da célula indicada
    Numero * aux;

    if(rm->seg == rm) { // se a celula for a cabeça
        free(rm); // desaloca rm
    } else { 
        aux = rm->ant;
        aux->ant->seg = rm;
        rm->ant = aux->ant;
        free(aux); // desaloca aux
    }
}


void insereLista(Numero *lst, int num)
{
    Numero *novo;
    novo = (Numero*) malloc(sizeof(Numero));
    novo->num = num; //acessa nova e bota o endereço da pessoa1 lá dentro;

    if(lst->seg == lst) {
        novo->seg = lst;
        lst->seg = novo;
        novo->ant = lst;
        lst->ant = novo;
        return;
    }
    novo->seg = lst->seg;
    lst->seg = novo;
    novo->seg->ant = novo;
    novo->ant = lst;
}


void geraLista(Numero *numero, int numeros) 
{
    int i;
    i=0;
    while (i != numeros) { // deve ser colocado 256 digitos
        insereLista(numero, gerarNumeros(2)); //GERANDO NUMEROS DE 0-1 E GUARDANDO NA LISTA
        i++;
    }
}
/*Cria uma lista*/
Numero * criaLista(int n)
{
    Numero * head;
    head = (Numero *) malloc(sizeof(Numero));
    head->num = n;
    head->seg = head;
    return head;

}

/*Imprime a lista caso o primeiro numero tenha um -1 é porque*/
/*o numero é negativo                                        */
void  imprimeLista(Numero * lst)
{
    //int i;
    Numero * aux;
    aux = lst->seg;
    //i=0;
    /*Imprimir o sinal*/
    if(lst->num == -1)  {
        printf("-");
    }

    while(aux != lst)
    {
        printf("%i", aux->num);
        aux = aux->seg;
        //i++;

    }


}
    
asked by anonymous 03.10.2017 / 15:00

2 answers

0

I just looked at the two functions you mentioned, so I do not know if there's anything else to change, but the right function should be for (i = 0; i

03.10.2017 / 18:21
0

Follow your re-adjusted code from a double-chained list. Just explain to me the way you want to split the list. Based on what?

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>

typedef struct nodo {
            int info;
            struct nodo *prox;
            struct nodo *ant;
} Nodo;

typedef struct {
    Nodo *primeiro;
} ListaDupla;

//Imprimir os elementos da lista na tela
void mostra(ListaDupla l){
     Nodo *p = l.primeiro;

     if (p != NULL) {
        while (p != NULL) {
            printf("%i ", p->info);
            p=p->prox;           
        }
    }
}

//Criar uma lista vazia
void cria(ListaDupla *lista) {
      lista->primeiro = NULL;
}

//Verificar se a lista á vazia
bool esta_vazia(ListaDupla l) {
    return l.primeiro == NULL;
}

//Aloca espaco de memoria para um novo nodo
Nodo *cria_nodo(int info) {
    Nodo * novo = (Nodo *)malloc(sizeof(Nodo));

    novo->info = info;
    novo->prox = NULL;
    novo->ant = NULL;
    return novo;
}

//Buscar um elemento qualquer na lista e retorná-lo (null se não encontrado)
Nodo *acha_elemento(ListaDupla *lista, int info) {
    Nodo *x = lista->primeiro;

    while (x != NULL && x->info != info) {
        x = x->prox;        
    }
    return x;
}

//Buscar o ultimo elemento
Nodo *acha_ultimo(ListaDupla *lista) {
    Nodo *x = lista->primeiro;

    if (x != NULL) {
        while (x->prox != NULL) {
            x = x->prox;
        }
        return x;
    }
    return NULL;
}

//Inserir um elemento no início da lista
void insere_inicio(ListaDupla *l, int i){
     Nodo *novo = cria_nodo(i);
     Nodo *p = l->primeiro, *anterior = NULL;

     while (p!=NULL && p->info < i) {
           anterior = p;
           p=p->prox;
     }
     novo->info=i;

     if (l->primeiro == NULL || anterior == NULL) { //lista vazia
       l->primeiro = novo;
     } else { // ou no inicio da lista
       anterior->prox = novo;
     }
     novo->prox = p;
     if (p != NULL) {//insere em lista vazia ou insere no final da lista
       p->ant=novo;
     }        
     novo->ant=anterior;     
}

//Inserir um elemento no fim da lista
void insere_fim(ListaDupla *lista, int info) {
    Nodo *ultimo = acha_ultimo(lista);

    if (ultimo != NULL) {
        Nodo *novo = cria_nodo(info);
        ultimo->prox = novo;
    } else {
        insere_inicio(lista, info);
    }   
}

//Retirar um elemento no final da lista
bool remove_fim(ListaDupla *lista) {
    if (!esta_vazia(*lista)) {
        Nodo *x = acha_ultimo(lista);

        if (x->ant == NULL && x->prox == NULL) { //unico elemento
            free(x);
            cria(lista);
        } else {
            Nodo *anterior = x->ant;

            anterior->prox = NULL;
            free(x);
        }
        return true;
    }
    return false;
}

//Retirar um elemento no inicio da lista
bool remove_inicio(ListaDupla *lista) { 
    if (!esta_vazia(*lista)) {
        Nodo *x = lista->primeiro;

        lista->primeiro = lista->primeiro->prox;
        lista->primeiro->ant = NULL;
        free(x);
        return true;
    }
    return false;
}

//Retirar um elemento qualquer da lista
bool remover(ListaDupla *l, int v) {
      Nodo *ant = NULL;
      Nodo *p = l->primeiro;

      while (p != NULL && p->info != v) {
            ant = p;
            p = p->prox;
      }
      if (p!=NULL) {         
         if (ant == NULL)
            l->primeiro=p->prox;
         else
            ant->prox=p->prox;
         free(p);
         return true;
      }
      return false;
}

/*Gerar numeros entre 0 ou 1 se n=2*/
int gerarNumeros(int n){
    return rand() % n ;
}

void geraSeed() { /* gera uma seed para nova sequencia de numeros aleatorios */
    srand((unsigned)time(NULL));
}

void geraLista(ListaDupla *numero, int numeros) 
{
    int i;
    i=0;
    while (i != numeros) { // deve ser colocado 256 digitos
        insere_fim(numero, gerarNumeros(2)); //GERANDO NUMEROS DE 0-1 E GUARDANDO NA LISTA
        i++;
    }
}

int main() {
    ListaDupla lista;//, lista_esq, lista_dir;
    int d;

    cria(&lista);
    printf("Insira a quantidade de DIGITOS do seu numero binario\n");
    scanf("%i", &d);
    printf("Criando o numero... \n\n");
    geraLista(&lista, d);
    mostra(lista);
    printf("\n\n\n");
    return 0;
}
    
03.10.2017 / 18:36