2015-02-06 316 views
1

我試圖編寫一個名爲「在鏈接列表中隔離偶數和奇數節點」的單鏈表列表程序,但無法退出while循環。無法退出while循環

我能夠成功地編譯和運行代碼。我一遍又一遍地追蹤程序超過四次,但無法找到catch。

我的意思

輸入 「在一個鏈表·隔離偶數和奇數節點」:17-> 15-> 8-> 12-> 10-> 5-> 4-> 1-> 7 - > 6-> NULL;輸出:8-> 12-> 10-> 4-> 6-> 17-> 15-> 5-> 1→7-> NULL

輸入:8-> 12-> 10-> 5- > 4-> 1-> 6-> NULL;輸出:8-> 12-> 10-> 4-> 6-> 5-> 1-> NULL

如果所有的數字都是偶數則不要更改列表 輸入:8-> 12-> 10- > NULL 輸出:8-> 12-> 10-> NULL

如果所有數值是奇數那麼不改變列表 輸入:1-> 3-> 5-> 7-> NULL 輸出:1 - > 3-> 5> 7> NULL

如何解決了這個問題:

溫度:遍歷列表。

evenPtr:指向偶數據節點的指針。

oddPtr:指向奇數據節點的指針。

oddPtrStart:跟蹤奇數據節點的開始。

My功能低於:

struct node *segregateEvenOddNodesSLL(struct node *temp) 
{ 
    struct node *evenPtr,*oddPtr,*oddPtrStart,*head=NULL; 

    head=temp; 

    while(1) 
    { 
     if(((temp->data)%2)==0) // even 
     { 

      if(evenPtr==NULL) 
      { 
       head=temp; 
       evenPtr=temp; 
      } 
      else 
      { 
       evenPtr->link=temp; 
       evenPtr=temp; 
      } 


     } 

     else    // odd 
     { 
      if(oddPtr==NULL) 
      { 
       oddPtrStart=temp; 
       oddPtr=temp; 
      } 
      else 
      { 
       oddPtr->link=temp; 
       oddPtr=temp; 
      } 



     } 

     temp=temp->link; 
     if(temp==NULL) 
     { 
      break; 
     } 

     printf("\n Inside While.... \n"); 

    }// end of while. 

    if(evenPtr==NULL) 
    { 
     return head; 
    } 
    else if(oddPtr==NULL) 
    { 
     return head; 
    } 
    else 
    { 
     oddPtr->link=NULL; 
     evenPtr->link=oddPtrStart; 

     return head; 
    } 


} 

呼叫與頭部= segregateEvenOddNodesSLL(頭)的功能;

像往常一樣單向鏈表的結構是:

struct node 
{ 
int data; 
struct node *link; 
}; 
+0

額外的(虛擬)信用:實施過程而不使用一個以上的'if' /'else'構建體或多於一個循環結構。 – 2015-02-06 19:34:56

回答

2

檢查以下行:

struct node *evenPtr,*oddPtr,*oddPtrStart,*head=NULL; 

需要是:

struct node *evenPtr=NULL,*oddPtr=NULL,*oddPtrStart=NULL,*head=NULL; 

這裏是我發現這個:

  1. 編譯器應該給你一個警告,你忘記初始化這些值。
  2. 單步執行時,您應立即注意到,while循環一到,oddPtr和/或evenPtr就不爲空。
+0

但我使用臨時指針存在while循環,而不是使用指針的其餘部分。 – munjal007 2015-02-06 19:18:31

+1

在進行循環出口測試之前,您閱讀了'evenPtr'和/或'oddPtr'的值(將它們與'NULL'進行比較)。這些變量是未初始化的,所以它們可以包含任何東西。它們可能包含垃圾,但是您可能會感到不幸,因爲其中一個或兩個包含與temp參數相同的值或指向列表中其他節點的指針,在這種情況下,第一次迭代你的循環將輸入列表轉換爲循環列表。 – 2015-02-06 19:45:38

+0

即使未初始化的變量具有無意義的值,它顯然是未能初始化它們的錯誤。修理它。 – 2015-02-06 19:47:01

2

首先,您要在初始化變量之前測試變量evenPtroddPtr的值。看起來你想在進入循環之前將它們中的每一個初始化爲NULL

這樣做,如果這...

temp=temp->link; 
    if(temp==NULL) 
    { 
     break; 
    } 

...永遠不會到達break觸發循環退出,你永遠不會得到一個分割故障或其他內存訪問錯誤,那麼最可能的解釋是,你的鏈表是圓形的。您可以通過在每次迭代中打印當前節點的data來解決這個問題。

請注意,循環後的代碼有缺陷:如果列表中沒有偶數項目,則所有節點都將丟失。

0

這是一個解決方案,它使用列表生成器來創建初始和偶數/奇數列表。我使用了一個輕微的「作弊」 - 一個列表最簡單的做法是以相反的順序製作,所以製作第二個偶數和奇數列表,將它們反轉到原始順序。

另一種方法可能是在原始列表上進行氣泡排序,如果'odd'出現在'even'之前,則交換數據字段,但這個答案試圖貼近OP做的事情。

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

struct node { 
    int data; 
    struct node *link; 
}; 

struct node* add_node(struct node *list, int id) { 
    struct node *n = malloc(sizeof (struct node)); 
    if (n == NULL) { 
     printf("Fatal Error: Out of memory!\n"); 
     exit(1); 
    } 
    n->data = id; 
    n->link = list; 
    return n; 
} 

struct node *segregateEvenOddNodesSLL(struct node *temp) { 
    struct node *odd=NULL,*even=NULL, *last = NULL; 
    while(temp) { 
     if(((temp->data)%2)==0) {  // even 
      even = add_node (even, temp->data); 
      if (last == NULL) 
       last = even; 
     } 
     else 
      odd = add_node (odd, temp->data); 
     temp = temp->link; 
    } 
    if(even) { 
     last->link = odd;   // append odd list 
     return even; 
    } 
    return odd; 
} 

void show (struct node *list) { 
    printf("List: "); 
    while(list != NULL) { 
     printf("%3d", list->data); 
     list = list->link; 
    } 
    printf("\n"); 
} 

void free_list(struct node *list) { 
    struct node *tmp; 
    while (list) { 
     tmp = list->link;  
     free(list); 
     list = tmp; 
    } 
} 

void make_list(int *array, int elements) { 
    struct node *list = NULL, *newlist; 
    int i; 
    printf("Array:"); 
    for (i=0; i<elements; i++) { 
     printf ("%3d", array[i]);    // show unsorted array 
     list = add_node(list, array[i]);  // make the linked list 
    } 
    printf("\n"); 
    newlist = segregateEvenOddNodesSLL(list); // sort it 
    show (newlist);        // show sorted list 
    printf ("\n"); 
    free_list (list); 
    free_list (newlist); 
} 

int main(void) { 
    int data1[10] = { 17, 15, 8, 12, 10, 5, 4, 1, 7, 6 }; 
    int data2[7] = { 8, 12, 10, 5, 4, 1, 6 }; 
    int data3[3] = { 8, 12, 10 }; 
    int data4[4] = { 1, 3, 5, 7 }; 

    make_list(data1, 10); 
    make_list(data2, 7); 
    make_list(data3, 3); 
    make_list(data4, 4); 
    return 0; 
} 

程序輸出:

Array: 17 15 8 12 10 5 4 1 7 6 
List: 8 12 10 4 6 17 15 5 1 7 

Array: 8 12 10 5 4 1 6 
List: 8 12 10 4 6 5 1 

Array: 8 12 10 
List: 8 12 10 

Array: 1 3 5 7 
List: 1 3 5 7