2010-03-15 9 views
1

Je suis novice en C et je travaille sur une liste liée XOR pour un projet. J'ai la plupart du code fait, mais je ne peux pas sembler obtenir la fonction de suppression de la liste pour fonctionner correctement. Il semble capable de supprimer certains nombres, mais pas n'importe quel nombre que vous passez dans la fonction. Est-ce que quelqu'un avec C pourrait jeter un coup d'oeil et peut-être indiquer où je me suis trompé? Je travaille sur ce sujet depuis un certain temps maintenant et n'ai pas eu beaucoup de chance et j'ai commencé plus de 3 fois :(Toute aide est très appréciée Merci Vous pouvez voir ma première tentative de code here Je ne peux publier qu'un seul lien , donc si vous voulez voir ma deuxième tentative, me le dire et je peux l'envoyer par courriel à vous ou quelque chose que vous remercions de votre tempsProblèmes avec la liste liée en C

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

struct node { 
     int data; 
     unsigned long link; 
}; 
struct node *head, *tail, *currN, *prevN, *nextN, *tmp; 

void insert(struct node **headN, struct node **tailN, int n); 
void delete(struct node **headN, struct node **tailN, int n); 
void list(struct node *head, int i); 
void nextNode(); 
void previNode(); 

//============================================================ 

void insert(struct node **headN, struct node **tailN, int numN) { 
    struct node *newnode = malloc(sizeof(struct node)); 
    newnode->link =(unsigned long)(*headN); 
    newnode->data = numN; 

    //if empty list 
    if (*headN == NULL){ 
      *headN = newnode; 
      currN = *headN; 
      (*headN)->link = 0; 
    } else if ((*headN)->link == (unsigned long)NULL){ 
      if (numN <= (*headN)->data){ 
       newnode->link = (unsigned long) *headN; 
       (*headN)->link = (unsigned long) newnode; 
       tail = *headN; 
       *headN = newnode; 
       nextN = tail; 
       prevN = NULL; 
      } else { 
       newnode->link = (unsigned long) *headN; 
       (*headN)->link = (unsigned long) newnode; 
       tail = newnode; 
       nextN = NULL; 
       currN = tail; 
       prevN = *headN; 
       } 
    } else { 
      currN = *headN; 
      prevN = NULL; 
      nextN = (struct node *)(currN->link^(unsigned long) prevN); 
      if (numN > tail->data){ 
       while (currN!=tail){ 
        nextNode(); 
       } 
       newnode->link = (unsigned long) currN; 
       currN->link = (unsigned long) newnode^(unsigned long) prevN; 
       tail = newnode; 
      } else if (numN < head->data){ 
       currN->link = (unsigned long) newnode^(unsigned long) nextN; 
       newnode->link = (unsigned long) currN; 
       *headN = newnode; 
       nextN = currN; 
       currN = *headN; 
      } else { 
       while (numN > currN->data){ 
        nextNode(); 
       } 
       newnode->link = (unsigned long) prevN^(unsigned long) currN; 
       prevN->link ^= (unsigned long) currN^(unsigned long) newnode; 
       currN->link ^= (unsigned long) prevN^(unsigned long) newnode; 
      } 
    } 
} 

void delete(struct node **headN, struct node **tailN, int numD){ 

    struct node *prevN = NULL; 
    struct node *currN = *headN; 

    while (currN != NULL) 
    { 
     struct node *nextN = (struct node *) (currN->link^(unsigned long)prevN); 
     //if the number is found, then delete it 
     if (currN->data == numD) 
     { 
      if(prevN) 
        { 
        prevN->link ^= (unsigned long)currN^(unsigned long)nextN; 
       } 
        else 
        *headN = nextN; 
       if(nextN) 
        { 
        nextN->link ^= (unsigned long)currN^(unsigned long)prevN; 
        } 
        else 
        *tailN = prevN; 
      free(currN); 
      break; 
     } 
      prevN = currN; 
     currN = nextN; 
    } 
} 

void list(struct node *head, int i){ 

    if(i == 0){ 
    currN = head; 
    prevN = NULL; 
    int count = 1; 
    nextN = (struct node *) (currN->link^(unsigned long) prevN); 
    printf("Linked List in ascending order\n"); 
    while(currN!=NULL){ 
      if(count <= 10){ 
       printf("%-5d", currN->data); 
       nextNode(); 
       count++; 
      } 
      else{ 
       printf("\n"); 
       count = 1; 
      } 
    } 
    } 
    printf("\n\n"); 

    if(i == 1){ 
    printf("Linked List in descending order\n"); 
    currN = tail; 
    int count2 = 1; 
    prevN = (struct node *) currN->link; 
    nextN = NULL; 
    while (currN!=NULL){ 
     if(count2 <= 10){ 
       printf("%-5d", currN->data); 
       previNode(); 
       count2++; 

      }else{ 
       printf("\n"); 
       count2 = 1; 
      } 
    } 
    } 
    printf("\n");   
} 

void nextNode(){ 
    nextN = (struct node *) (currN->link^(unsigned long) prevN); 
    prevN = currN; 
    currN = nextN; 
} 

void previNode(){ 
    prevN = (struct node *) (currN->link^(unsigned long) nextN); 
    nextN = currN; 
    currN = prevN;  
} 

int main(){ 

    int i, num; 
    float seed; 
    head = NULL; tail = NULL; currN = NULL; prevN = NULL; nextN = NULL; 

    init_seed(1234567); 
    set_range(1,9999); 
    //inserting data into the linked list 
    for (i=0; i<100; ++i){ 
     num = rndm(); 
     insert(&head, &tail, num); 
    } 

    list((struct node*)head, 0); 
    //delete((struct node**)head, (struct node**)tail, 45); 
    //delete((struct node**)head, (struct node**)tail, 4040); 
    //delete((struct node**)head, (struct node**)tail, 9769); 
    list((struct node*)head, 1); 


    return 0; 
} 
+2

S'il vous plaît poser une question spécifique, votre code est beaucoup trop longtemps à lire. – zellio

+0

WTF est une liste XOR liée? :-) – paxdiablo

+0

Pouvez-vous indétecter des parties du code où vous frappez seg-faute? – dirkgently

Répondre

0

Une note sur votre code:..

Le node.link ne devrait pas être un unsigned long il puisque cela suppose des caractéristiques de votre compilateur/plate-forme

EDIT: Peut-être que je mésusage d sur la liste liée XOR, discussion.

EDIT 2: (comme suggéré par @Matthew Flaschen) utilisez intptr_t pour rendre votre code plus portable.

+0

Pourquoi devrait-il s'agir d'un 'struct node '? Et ça devrait être un commentaire. –

+0

@tusbar Ok, avec une liste liée XOR n'est peut-être pas si facile, mais on dirait que le code suppose que la taille d'une référence à un nœud de la même taille qu'un entier non signé, ce qui n'est vrai que sur certaines plateformes/compilateurs. –

+0

Cela est vrai, sur LLP64 'sizeof (ptr)' est 64 bits et 'sizeof (long)' est 32. –

5

Il semble que vous ayez pris du code sur Internet et essayé de l'utiliser.

Le code fonctionne très bien, vous ne savez pas ce qu'est un pointeur.

Vous faites:

delete((struct node**)head, (struct node**)tail, 45); 

Et voici les définitions des variables head et tail:

struct node { 
    int data; 
    unsigned long link; 
}; 
struct node *head, *tail, *currN, *prevN, *nextN, *tmp; 

Le prototype de la fonction delete() est void delete(struct node **headN, struct node **tailN, int numD);

« Oh la le compilateur demande struct node **, jetons-le ". Ce n'est pas comme ça que ça fonctionne.

Essayez ceci:

delete(&head, &tail, 45); 
+0

Ok, donc en utilisant & head & & tail je passe dans l'adresse droite? J'ai essayé cela, 45 était capable de supprimer très bien, mais quand j'ai essayé de supprimer 4040 et 9769, ils ne semblaient pas supprimer parce qu'ils apparaissent encore dans la liste lorsque je l'imprime après avoir appelé la fonction de suppression. – seePhor

+0

http://codepad.org/wWW5ZUHS –

+0

Qu'avez-vous fait/changé? – seePhor

-1

En regardant la fonction delete me demande au sujet de cette manipulation de pointeur, par la manière, vous utilisez adresse des paramètres si vraiment il devrait être delete(&head, &tail, 45);

passer de cette ....

 
void delete(struct node **headN, struct node **tailN, int numD) 
{ 
    struct node *prevN = NULL; 
    struct node *currN = *headN; 
    struct node *tempNode = NULL; 

    while (currN != NULL) 
    { 
     struct node *nextN = (struct node *) (currN->link^(unsigned long)prevN); 
     //if the number is found, then delete it 
     if (currN->data == numD) 
     { 
      if(prevN) 
      prevN->link ^= (unsigned long)currN^(unsigned long)nextN; 
      else 
      *headN = nextN; 
      if(nextN) 
      nextN->link ^= (unsigned long)currN^(unsigned long)prevN; 
      else 
      *tailN = prevN; 
      /* Sanity check here...you could be screwing up the list 
      ** by calling free(currN) 
      */ 
      tempNode = currN; 
      free(tempNode); 
      /* free(currN); <-- That could be misleading... */ 
      break; 
     } 
     prevN = currN; 
     currN = nextN; 
    } 
} 

cette modification du code est de veiller à ce que currN est cohérente, regardant avec des yeux sur la manipulation du pointeur, cela pourrait être discutable, comme la liste pourrait se retrouver brisée en faisant un free sur le currN ... juste pour être sûr ...

+1

Je ne vois pas ce que votre amendement fait. currN est supprimé de la liste, de sorte que le noeud est en cours de libération. Vous faites la même chose, juste avec une variable pointeur supplémentaire. Bien sûr, le 'prevN = currN; currN = nextN; 'ne pas s'exécuter en raison de' break' (dans ce cas, la rupture est effectivement un 'return') –

+0

Cela a fonctionné! Alors, quels problèmes étaient libres (currN) provoquant exactement? – seePhor

+0

@seePhor: Je pensais en fait à iterating à travers une liste liée comme '' while (currN! = Null) ', que currN pourrait finir par être libéré et casser la boucle while ... d'où la nécessité de l'assigner temporairement à un autre pointeur pour libérer ... tempNode = currN; currN = currN-> suivant; libre (tempNode); Peut-être que je me suis mélangé ... et j'ai pensé que ça s'appliquerait ici ... – t0mm13b