2017-08-24 18 views
0

リンクリストでいくつかのエクササイズをしています。リンクリストの素数であるインデックスにノードを削除する関数を書く必要があります。例えば、リンクされたリストがある場合:Cのリンクリストのプライムインデックスでノードを削除

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

返されたリストがある必要があります:私は書く必要がある機能で私を助けるために機能delete(Node* list)isPrime(int n)を書いた

6->2->1->NULL. 

。しかし、私はセグメンテーション違反を続けています。 delete(Node* list)ファンクションとisPrime(int n)ファンクションワークは、私はこの問題がprimes(Node* list)にあると信じています。

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

'削除のボイド(int型nは、ノード*ヘッド){...ヘッド= ...}は、'非常に高いのは意味がありません。リストの最初の要素を削除した場合、リストの先頭を別の要素にターゲット変更する必要があります。したがって、 'delete'のシグネチャは' void delete(int n、Node ** head) 'のようになります。 @StephanLechner。 –

+0

OPは素数であるインデックスのノードを削除しています。「1」は素数ではないので、それは問題にはなりません。 –

+1

ノードを削除すると、次のノードの番号はすべて1ずつ先に移動するため、もはや正しいとは言えません。 – interjay

答えて

1

あなたは1つの要素を削除したら意味がありません。最初から数えて、WhozCraigで説明したように:

は、ここに私のコードです。

しかし、最初から反復された要素の数を数えながらリストを1つずつ反復するだけで、インデックスが素数であれば要素を削除するか、単にスキップするだけで済みます。 primesだけになる:

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

私は、DPを 'IsPrime(i)'に使うことを提案します。 – roottraveller

関連する問題