2013-10-07 66 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循环是否合适。