【问题标题】:compare list items, and sort in order in c比较列表项,并在 c 中按顺序排序
【发布时间】:2012-11-26 14:06:53
【问题描述】:

代码已编译,但是我的代码中存在逻辑错误。我想比较数组中的字符串,然后在列表中按顺序列出它们。我不知道如何在不使用索引的情况下比较列表项,以及如何将当前名称与下一个名称进行比较。任何人都可以帮忙吗?

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


/* these arrays are just used to give the parameters to 'insert',
   to create the 'people' array */
char names[][10]= {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim",
      "Harriet"};
int ages[7]= {22, 24, 106, 6, 18, 32, 24};


/* declare your struct for a person here */
typedef struct Record{
    char *name;
    int age;
    struct Record *next;
}   Record;

//set the head pointer at the start of the list
Record *headptr = NULL;

int compare_people( Record *a, Record *b)
{
     return strcmp((*(Record *)a).name, (*(Record *)b).name);
}

static void insert (Record *p, char *s, int n) {

    /* create a new space for the new person */
    Record *ptr = ( Record *) malloc(sizeof(Record));

    /* check if it is succeeded  */ 
    if( ptr == NULL){  
        abort();
        printf("memory allocation fail"); 
        exit(1);  
    }else{
        printf("memory allocation to person  - %s - \n", s);      
    }

    //set the data for the new person
    ptr->name=s;
    ptr->age=n;
    ptr->next= NULL;

    //ptr= NULL; 
    //printf("%i", p->age);


    /*  do not compare when the list is empty*/
    if(headptr==NULL)
    {
        ptr->next=headptr;
        headptr=ptr;
        printf("ok1\n");

    }else{
        Record *tail = headptr;

        /* go through all the list */
        while(tail->next!=NULL)
        {     
            if(compare_people(ptr->name,tail->name)== 1){
            tail = tail->next;
        }else{
            tail->next=headptr;
            }
        }//while

        //tail->next=ptr;
    }  
}  

int main( int argc, char **argv) {

    /* declare the people array here */
    Record *p=headptr;
    headptr = NULL;

    //insert the members and age into the unusage array. 
    for (int i=0; i < 7; i++) {
         insert (p,names[i], ages[i]);
         /* do not dereference the pointer */
    }

    /* print out a line before printing the names and ages */
    printf("\n");

    //set the pointer at the start of the list 
    p = headptr;

    /* print the people array here*/
    for ( int i=0; i < 7; i++, p = p->next ) {
        printf("The name is: %s, the age is:%i\n", p->name, p->age);
    }


    /* This is the third loop for call free to release the memory allocated by malloc */
    /* the free()function deallocate the space pointed by ptr. */
    for( int i=0; i<7; i++){
        free(p->next);
    } 
}

【问题讨论】:

    标签: c sorting linked-list


    【解决方案1】:

    这段代码看起来不对:

    Record *tail =headptr;
    /* go through all the list */
    while(tail->next!=NULL)
    {   
      if(compare_people(ptr->name,tail->name)== 1){
        tail = tail->next;
      } else {
        tail->next=headptr;
      }
    } //while
    

    如果你想在tail 之后插入一些东西,简单地设置tail-&gt;next = headptr 将会(a)泄漏tail 之后的任何东西,并且(b)把你的链表变成一个没有结束的循环。

    如果你想将ptr 插入到你的列表中,你可能应该这样做

    ptr->next = tail->next; 
    tail->next = ptr; 
    

    ...然后跳出循环。

    【讨论】:

    • @user1851359:整体方法看起来不错,但您有一些错误需要修复才能正常工作。
    • ptr->next = tail->next;尾->下一个 = ptr;这段代码是放在 compare_people 之后的吗?
    • 是的,在您实际插入节点的 else 块内。还要确保break退出循环,否则你可能会多次插入同一个节点。
    【解决方案2】:

    第一个主要问题在这里:

    Record *tail =headptr;
    /* go through all the list */
    while(tail->next!=NULL) {
    ...
    

    你永远不会进入这个while() 循环。在第一次迭代中,您这样做了:

    ptr->next= NULL;  // setting the pointer's next pointer to NULL
    ...
    headptr=ptr;     // have headptr point at what ptr is pointing to
    

    这意味着headptr-&gt;next 将是NULL。然后在上面的代码 sn-p 中将tail 设置为headptr,因此tail-&gt;next 将是NULL,并且您将永远不会执行该循环。

    第二个主要问题来了:

    if(compare_people(ptr->name,tail->name)== 1){
    

    您正在向该函数传递一个字符串(record->name 是一个字符串),但在函数本身中您已将其设置为:

    int compare_people(Record *a, Record *b)
    

    将记录(不是char *)作为输入。一旦你解决了第一个问题并真正使用了这个函数,这会杀了你。

    【讨论】:

    • 现在它正在执行循环,但是 cmp 名称是否正确?如果我想按顺序打印出名字?
    • @user1851359 - 好吧,我不太确定你想用compaire做什么。从strcmp 返回 1 会检查 ptr->name 中第一个不匹配字符的值是否大于 tail->name。你为什么关心这个?您是否真的在尝试检查它们是否相等?
    【解决方案3】:

    您的代码包含许多错误。我无法检查您的代码和 cmets 的所有错误。我试图修复你的代码。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char names[][10]= {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim",
          "Harriet"};
    int ages[7]= {22, 24, 106, 6, 18, 32, 24};
    
    
    /* declare your struct for a person here */
    typedef struct Record{
      char *name;
      int age;
      struct Record *next;
    }  Record;
    
    //set the head pointer at the start of the list
    Record *headptr = NULL;
    
    int compare_people(char *a, char *b)
    {
    
      return strcmp(a, b);
    }
    
    void insert (char *s, int n) {
         Record *t, *pnew, *prv;
         int i;
         prv=NULL;
         pnew=(Record *)malloc(sizeof(struct Record));
         if(pnew == NULL){  
            abort();
            printf("memory allocation fail"); 
            exit(1);  
        }else{
            printf("memory allocation to person  - %s - \n", s);      
        }
         pnew->name = s;
         pnew->age = n;
         pnew->next = NULL;
         if (headptr==NULL)
         {
            headptr = pnew;
            return;
         }
         for (t=headptr;t!=NULL;t=t->next) { // look for the right place to insert in order to get a tri list
             if (compare_people(s,t->name)<0) {        
                pnew->next=t;
                if (prv!=NULL)
                   prv->next = pnew;
                else
                   headptr=pnew;
                return;
             }
             prv=t;
         }
         prv->next=pnew;
         return;       
    }
    
    int main(int argc, char **argv) {
    
      Record *p, *q;
      int i;
    
      for (i=0; i < 7; i++) {
         insert (names[i], ages[i]);
      }
    
       printf("\n");
    
      for (p = headptr; p!=NULL; p = p->next) {
        printf("The name is: %s, the age is:%i\n", p->name, p->age);
      }
    
    
      /* To free your linked list: */
      p = headptr;
      while (p!=NULL){
        q = p;
        p = p->next;
        free(q);
      }
    }
    

    上述代码执行的输出:

    linux$ ./test
    memory allocation to person  - Simon - 
    memory allocation to person  - Suzie - 
    memory allocation to person  - Alfred - 
    memory allocation to person  - Chip - 
    memory allocation to person  - John - 
    memory allocation to person  - Tim - 
    memory allocation to person  - Harriet - 
    
    The name is: Alfred, the age is:106
    The name is: Chip, the age is:6
    The name is: Harriet, the age is:24
    The name is: John, the age is:18
    The name is: Simon, the age is:22
    The name is: Suzie, the age is:24
    The name is: Tim, the age is:32
    

    【讨论】:

      【解决方案4】:

      您可能必须使用双重链表(添加指向列表前一条记录的指针)。然后将更容易对列表的元素进行排序。希望对你有帮助。

      【讨论】:

      • 我会试试的。你知道代码是否也会对列表进行排序吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多