2013-10-07 106 views
0

我比較新的指針C &。我正在嘗試排序,然後打印一個結構鏈表。要麼我錯過了一個邏輯錯誤,要麼我沒有完全理解指針。有人可以向我解釋我在這段代碼中缺少的東西嗎?提前謝謝你!無限循環與指針 - 爲什麼?

// *** Sort Linked List (Merge Sort) *** 

struct address_node *newRoot; 

// ptr, rearPtr, and tempRoot are also struct Pointers 
newRoot = root; 
root = root->next; 

while (root != NULL) 
{ 
    tempRoot = root; 
    ptr = newRoot; 
    rearPtr = newRoot; 

    while (ptr != NULL) 
    { 
     printf("here"); 
     if ((root->frequency) == (ptr->frequency)) 
     {      // SPECIAL CASE: To determine read hierarchy for repeated 
           // Entries 
      if ((root->read_order) < (ptr->read_order)) 
      { 
       if (ptr == newRoot) 
       { 
        root = root->next; 
        tempRoot->next = newRoot; 
        newRoot = tempRoot; 
        ptr = NULL; 
       } 
       else 
       { 
        root = root->next; 
        tempRoot->next = ptr; 
        rearPtr->next = tempRoot; 
        ptr = NULL; 
       } 
      } 
     } 
     else if ((root->frequency) > ptr->frequency) 
     {      // To ADD BEFORE an ENTRY 
      if (ptr == newRoot) 
      { 
       root = root->next; 
       tempRoot->next = newRoot; 
       newRoot = tempRoot; 
       ptr = NULL; 
      } 
      else 
      { 
       root = root->next; 
       tempRoot->next = ptr; 
       rearPtr->next = tempRoot; 
       ptr = NULL; 
      } 
     } 
     else if (ptr->next == NULL) 
     {      // if END OF LIST 
      root = root->next; 
      ptr->next = tempRoot; 
      ptr = NULL; 
     } 
     else 
     {      // SPOT NOT FOUND YET< MOVE FORWARD THROUGH LIST 
      rearPtr = ptr; 
      ptr = ptr->next; 
     } 
    } 
} 

// *** PRINT *** 
ptr = newRoot; 
if (numOut == 0) 
{ 
    while (ptr != NULL) 
    { 
     printf("0x%zx :%d\n", ptr->address, ptr->frequency); 
     ptr = ptr->next; 
    } 
} 
else 
{ 
    while (ptr != NULL && numOut > 0) 
    { 
     printf("0x%zx :%d\n", ptr->address, ptr->frequency); 
     numOut--; 
     ptr = ptr->next; 
    } 
} 
+0

目前循環永不退出? – canhazbits

+0

要做的第一件事是編寫兩個單獨的函數(至少),一個合併排序鏈接列表,另一個打印鏈接列表。您將使用打印功能在各個階段打印鏈接列表,同時調試您的排序代碼。這些函數應該列出一個列表(對於打印函數,我推薦一個'標籤' - 一個字符串,它將在列表內容之前打印出來 - 也可能是文件流:void print_list(const char * tag,struct address_node const * list)'或'void print_list(FILE * fp,const char * tag,struct address_node const * list)')。 –

+0

列表的經典合併排序算法將給定列表拆分爲兩個單獨列表,合併排序每個單獨列表(遞歸),然後將生成的已排序單獨列表合併到輸出列表中。你的代碼似乎沒有遵循這種模式。請在SO搜索框中查找'[c]合併排序列表'。它可能會導致你[使用mergesort排序鏈表](http://stackoverflow.com/questions/19016840/using-mergesort-to-sort-linked-lists/),也可能導致其他問題。 –

回答

1

所有的指針似乎指向相同的東西,根。因此,在一個實例中,root會向前移動,但是您可以指向root-> next指向root後面的內容。所以想象一下,根指向bob和根 - >下一個點要計費,假設你的第一個嵌套的if全部變爲真,root = bill但是root-> next = bob。沒有前進的動作正在進行。

0

您無法確保root在內循環的每次迭代中都更新。例如,假設您的代碼本儀表的變化:

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

struct address_node 
{ 
    struct address_node *next; 
    int frequency; 
    int read_order; 
}; 
static void sort_list(struct address_node * *root); 
static void print_list(char const *tag, struct address_node const *root); 

int main(void) 
{ 
    struct address_node data[] = 
    { 
     { &data[1], 43, 0 }, 
     { &data[2], 23, 1 }, 
     { &data[3], 13, 2 }, 
     { &data[4], 27, 3 }, 
     { &data[5], 57, 4 }, 
     { &data[6], 17, 5 }, 
     { &data[7], 27, 6 }, 
     { &data[8], 20, 7 }, 
     { &data[9], 30, 8 }, 
     {  NULL, 50, 9 }, 
    }; 
    struct address_node *root = &data[0]; 

    print_list("Before", root); 
    sort_list(&root); 
    print_list("After", root); 
} 

static void sort_list(struct address_node **proot) 
{ 
    struct address_node *root = *proot; 
    struct address_node *newRoot; 
    struct address_node *ptr; 
    struct address_node *rearPtr; 
    struct address_node *tempRoot; 

    printf("-->> %s: root 0x%.12" PRIXPTR "\n", __func__, (uintptr_t)root); 
    newRoot = root; 
    root = root->next; 


    while (root != NULL) 
    { 
     tempRoot = root; 
     ptr = newRoot; 
     rearPtr = newRoot; 

     while (ptr != NULL) 
     { 
      printf("here 1: root 0x%.12" PRIXPTR "\n", (uintptr_t)root); 
      if (root->frequency == ptr->frequency) 
      { 
       printf("here 2: root 0x%.12" PRIXPTR "\n", (uintptr_t)root); 
       if (root->read_order < ptr->read_order) 
       { 
        if (ptr == newRoot) 
        { 
         root = root->next; 
         tempRoot->next = newRoot; 
         newRoot = tempRoot; 
         ptr = NULL; 
         printf("here 2A: root 0x%.12" PRIXPTR "\n", (uintptr_t)root); 
        } 
        else 
        { 
         root = root->next; 
         tempRoot->next = ptr; 
         rearPtr->next = tempRoot; 
         ptr = NULL; 
         printf("here 2B: root 0x%.12" PRIXPTR "\n", (uintptr_t)root); 
        } 
       } 
       else 
        printf("here 2C: root 0x%.12" PRIXPTR "\n", (uintptr_t)root); 
      } 
      else if (root->frequency > ptr->frequency) 
      { 
       printf("here 3: root 0x%.12" PRIXPTR "\n", (uintptr_t)root); 
       if (ptr == newRoot) 
       { 
        root = root->next; 
        tempRoot->next = newRoot; 
        newRoot = tempRoot; 
        ptr = NULL; 
        printf("here 3A: root 0x%.12" PRIXPTR "\n", (uintptr_t)root); 
       } 
       else 
       { 
        root = root->next; 
        tempRoot->next = ptr; 
        rearPtr->next = tempRoot; 
        ptr = NULL; 
       printf("here 3B: root 0x%.12" PRIXPTR "\n", (uintptr_t)root); 
       } 
      } 
      else if (ptr->next == NULL) 
      { 
       printf("here 4: root 0x%.12" PRIXPTR "\n", (uintptr_t)root); 
       root = root->next; 
       ptr->next = tempRoot; 
       ptr = NULL; 
      } 
      else 
      { 
       printf("here 5: root 0x%.12" PRIXPTR "\n", (uintptr_t)root); 
       rearPtr = ptr; 
       ptr = ptr->next; 
      } 
     } 
    } 
    *proot = root; 
    printf("<<-- %s: root 0x%.12" PRIXPTR "\n", __func__, (uintptr_t)root); 
} 

static void print_list(char const *tag, struct address_node const *root) 
{ 
    printf("%s: 0x%.12" PRIXPTR "\n", tag, (uintptr_t)root); 
    while (root != NULL) 
    { 
     printf("0x%.12" PRIXPTR " : %2d %2d\n", 
       (uintptr_t)root, root->frequency, root->read_order); 
     root = root->next; 
    } 
} 

輸出我得到的開始:

Before: 0x7FFF5382D440 
0x7FFF5382D440 : 43 0 
0x7FFF5382D450 : 23 1 
0x7FFF5382D460 : 13 2 
0x7FFF5382D470 : 27 3 
0x7FFF5382D480 : 57 4 
0x7FFF5382D490 : 17 5 
0x7FFF5382D4A0 : 27 6 
0x7FFF5382D4B0 : 20 7 
0x7FFF5382D4C0 : 30 8 
0x7FFF5382D4D0 : 50 9 
-->> sort_list: root 0x7FFF5382D440 
here 1: root 0x7FFF5382D450 
here 5: root 0x7FFF5382D450 
here 1: root 0x7FFF5382D450 
here 2: root 0x7FFF5382D450 
here 2C: root 0x7FFF5382D450 
here 1: root 0x7FFF5382D450 
here 2: root 0x7FFF5382D450 
here 2C: root 0x7FFF5382D450 
here 1: root 0x7FFF5382D450 
here 2: root 0x7FFF5382D450 
here 2C: root 0x7FFF5382D450 
here 1: root 0x7FFF5382D450 
here 2: root 0x7FFF5382D450 
here 2C: root 0x7FFF5382D450 
here 1: root 0x7FFF5382D450 
here 2: root 0x7FFF5382D450 
here 2C: root 0x7FFF5382D450 

它沒有得到這之後的任何更精彩。我相信,您需要內循環在每次迭代中前進,因此您需要確保每次都更新root。條款(5)else根本不會改變root; (2C)條款也沒有。所以,你需要回去並確保root在每次迭代中都得到適當的更新。如果更改始終爲root = root->next;,則應調查for作爲重新初始化條件的root = root->next循環是否合適。