2017-08-24 4 views
0

Ich mache einige Übung mit verknüpften Listen und stieß auf diese: Ich muss eine Funktion schreiben, die die Knoten bei Indizes, die Primzahlen in einer verketteten Liste sind, löscht. Zum Beispiel, wenn die verknüpfte Liste ist:Löschen Knoten in Primindexe in einer verketteten Liste in C

6->3->5->2->7->1->NULL 

die zurückgegebene Liste sein muss:

6->2->1->NULL. 

Ich habe Funktionen geschrieben delete(Node* list) und isPrime(int n) mir zu helfen, mit der Funktion muss ich schreiben. Aber ich bekomme immer einen Segmentierungsfehler. Die delete(Node* list) Funktion und isPrime(int n) Funktion funktionieren, ich glaube, das Problem ist in primes(Node* list).

Hier ist mein Code:

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

void printList(Node* list) { 
    if(list->next == NULL) { 
     printf("%d\n", list->data); 
    } 
    else { 
     printf("%d ", list->data); 
     printList(list->next); 
    } 
} 

Node* addLast(Node* list, int x) { 
    Node* head = list; 
    if(head == NULL) { 
     Node* new = (Node*) malloc(sizeof(Node)); 
     new->data = x; 
     new->next = NULL; 
     return new; 
    } 
    else { 

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

     Node* new = (Node*) malloc(sizeof(Node)); 
     new->data = x; 
     new->next = NULL; 

     head->next = new; 
     return list; 
    } 
} 

void delete(int n, Node* head) { 
    Node* temp = head; 
    if(n == 0) { 
     head = temp->next; 
     free(temp); 
    } 
    else { 
      int i; 
      for(i = 0 ; i < (n-2); i++) { 
       temp = temp->next; 
      } 

      Node* temp1 = temp->next; 
      temp->next = temp1->next; 
      free(temp1); 
    } 
} 

bool isPrime(int n) { 
    int flag = 0; 
    if(n == 1) { 
     return false; 
    } 

    else { 
     int i; 
     for(i = 2; i < n; i++) { 
      if(n%i == 0) { 
       flag = 1; 
       break; 
      } 
     } 

     if(flag == 0) { 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 
} 

Node* primes(Node* list) { 
    Node* temp = list; 
    int i = 1; 
    while(temp != NULL) { 

     if(isPrime(i)) { 
      delete(i-1, temp); 
     } 
     else { i++; } 
     temp = temp->next; 

    } 
    return list; 
} 

int main() { 
    int n, st, i; 
    scanf("%d", &n); 

    Node* head = NULL; 

    for(i = 0; i < n; i++) { 
     scanf("%d", &st); 
     head = addLast(head, st); 
    } 
    printList(head); 

    printList(primes(head)); 


    return 0; 
} 
+0

'Leere delete (int n, Knoten * Kopf) {... head = ...}' sehr wahrscheinlich macht keinen Sinn; Wenn Sie das erste Element der Liste gelöscht haben, dann muss der Kopf der Liste auf ein anderes Element neu ausgerichtet werden, und die Signatur von "delete" sollte daher etwas wie "void delete (int n, Node ** head)" sein. –

+0

@StephanLechner. OP löscht Knoten bei Indizes, die prime sind. Da "1" nicht prim ist, wird das kein Problem sein. –

+1

Nachdem Sie einen Knoten gelöscht haben, sind die Nummern der folgenden Knoten nicht mehr korrekt, da sie alle um 1 vorrücken. – interjay

Antwort

1

Wie WhozCraig erklärt, von Anfang an zu zählen ist nicht sinnvoll, wenn Sie ein einzelnes Element löschen.

Aber Sie könnten einfach die Liste ein Element nach dem anderen iterieren, indem Sie die Anzahl der von Anfang an iterierten Elemente zählen und einfach entweder ein Element entfernen, wenn sein Index prim ist, oder einfach überspringen. primes würde einfach geworden:

Node* primes(Node* list) { 
    Node* temp = list; 
    int i = 1;     // trick: we know 1 is not prime so skip it 
    while (temp->next != NULL) { // and it is easier to delete next element than current one 
     i++; 
     if (isPrime(i)) { 
      delete(1, temp);  // delete if index is prime 
     } 
     else temp = temp->next;  // else skip 
    } 
    return list;     // done with it... 
} 
+0

Ich empfehle die Verwendung von DP für 'IsPrime (i)' – roottraveller

Verwandte Themen