2017-08-24 67 views
0

我正在做一些有關鏈接列表的練習,並且遇到了這個問題:我需要編寫一個函數,該函數刪除鏈接列表中素數爲索引的節點。例如,如果鏈表是:刪除鏈接列表中的主要索引中的節點C

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

返回列表必須是:

6->2->1->NULL. 

我寫功能delete(Node* list)isPrime(int n)幫助我,我需要寫函數。但我不斷收到分段錯誤。 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)'。 –

+0

@StephanLechner。 OP正在刪除素數爲指數的節點。由於'1'不是素數,所以這不會成爲問題。 –

+1

刪除一個節點後,以下節點的數量將不再正確,因爲它們將全部向前移動1. – interjay

回答

1

正如WhozCraig解釋,從一開始計數,一旦你有刪除一個單一的元素是沒有意義的。

但是,您可以簡單地迭代列表中的一個元素,一次計算從開始迭代的元素數量,並且只需刪除元素(如果其索引爲素數或僅跳過它)。 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

我建議在'IsPrime(i)'中使用DP – roottraveller