使用列表,按升序放置数字

时间:2018-05-05 23:19:32

标签: c

如何使此代码按升序排列?

我有点新的列表,我真的想以此为例, 并且没有来自headerfiles的任何函数。(除了malloc我猜)

作为第一个即时收到错误(.exe停止工作),不知道它来自哪里。(可能是当执行appendref时)

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


struct box{
    int value;
    struct box*next;
};
typedef struct box Box;

Box *createbox(int a){
    Box *newbox_ptr;
    newbox_ptr=malloc(sizeof(Box));
    newbox_ptr->next=NULL;
    newbox_ptr->value=a;
    return newbox_ptr;
}
void report(Box *mylist_ptr){
    if(mylist_ptr==NULL){
        return;
    }
    printf("%d:",mylist_ptr->value);
    report(mylist_ptr->next);
    return;
}
void appendref(Box **start_ptrptr,Box *node_ptr){
    Box *iter=*start_ptrptr;
    if(iter==NULL){
        printf("Called with empty list\n");

        *start_ptrptr=node_ptr;
    }
    for(;iter->next!=NULL;iter=iter->next);
    iter->next=node_ptr;
    return;
}
int main(){
    Box *mylist=NULL;
    Box *new_ptr;
    new_ptr=createbox(7);
    report(new_ptr);
    printf("%p\n",(void *)mylist);
    appendref(&mylist,new_ptr);
    printf("%p\n",(void *)mylist);
    report(mylist);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

代码在函数appendref中执行分段错误:

for(;iter->next!=NULL;iter=iter->next);

那是因为局部变量iter等于NULL,即:

void appendref(Box **start_ptrptr,Box *node_ptr){
    Box *iter = *start_ptrptr; // *start_ptrptr = NULL
    if(iter==NULL){ // this is true
        printf("Called with empty list\n");

        *start_ptrptr = node_ptr;
        // iter = NULL, and we go on...
    }
    for(;iter->next!=NULL;iter=iter->next); // iter = NULL -> segfault
    iter->next=node_ptr;
    return;
}

我建议在if语句中添加一个return:

void appendref(Box **start_ptrptr,Box *node_ptr){
    Box *iter = *start_ptrptr;
    if(iter == NULL){
        printf("Called with empty list\n");
        *start_ptrptr = node_ptr;
        return;
    }
    for(;iter->next!=NULL;iter=iter->next);
    iter->next=node_ptr;
}

至于按升序排列数字,代码需要更多的工作:

void appendref(Box **head,Box *node) {
    // if the list is empty, just append node_ptr to the list
    if(*head == NULL){
        *head = node;
        return;
    }
    // find Box with value lower then node->value, but the next Box has higher value then node->value
    if ((*head)->value > node->value) {
        // insert new head
        node->next = *head;
        *head = node;
    } else {
        Box *iter = *head;
        for(iter = *head; iter->next != NULL; iter = iter->next) {
            assert(iter->value <= iter->next->value); // assert the list is sorted in ascending order
            // break if the next node has higher value then added node
            if (iter->next->value > node->value)
                break;
        }
        // insert node after iter
        node->next = iter->next;
        iter->next = node;
    }
}

您可能会对sys/queue.h中来自* bsd的宏的通用列表感兴趣。