【问题标题】:Function that Inserts a node into a linked list sorted将节点插入到排序的链表中的函数
【发布时间】:2017-07-07 00:09:57
【问题描述】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_MODEL 25
#define MAX_LINE 50
typedef struct car{
    char* model;
    char* color;
    int year;
    struct car* next;
}car;
car* readFromFile(FILE*);
car* insertInSortedOrder(car*, char*, char*, int);
car* createCar(char*, char*, int);
void printCars(car*);

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

    //creating a file pointer, opening file
    FILE* fptr;
    fptr = fopen(*(argv+1), "r");
    car* head = NULL;

    //this first reads cars from files, puts it into linked list and prints
    head = readFromFile(fptr);
    puts("do we get here");
    printCars(head);
    return 0;
}
///this function reads information from a text file, sends it to insertInSortedOrder function
car* readFromFile(FILE* fptr){

    char *M, *C, *year;
    char *readLine= malloc(sizeof(car)*MAX_MODEL);
    int yr;

    car *head=NULL;
    while(fgets(readLine,MAX_LINE,fptr)!= NULL){
            M = strtok(readLine,"|");
            C = strtok(NULL,"|");
            year = strtok(NULL,"|");
            yr = atoi(year);
            head = insertInSortedOrder(head,M,C,yr);
    }
    return head;
}
//this function sends new info to createCar to put it into a list, gets it and puts it
//into sorted order according to alphabetical order by model
car* insertInSortedOrder(car* head, char* model, char* color, int year){

    //if list is emppty
    if(head == NULL){
            head = createCar(model,color,year);
    }
    else{
            car *new = createCar(model,color,year);
            car *current,*previous;
            current = head;
            previous = NULL;
            puts("here?");
            //compares new car model to next model, if  next is greater than new, move onto next pair
            while(strcmp(new->model,current->model) < 0){
            puts("here2");
            previous = current;
            current = current->next;
            puts("here2.5");
            }
            puts("here3");
            //if only one thing in the list
            if(previous->next == NULL){
                    //new car is next on list
                    if(strcmp(previous->model,new->model) > 0){
                            previous->next = new;
                    }
                    //new car goes into top of list
                    else{
                            head = new;
                            head->next = previous;
                    }
            }
            //doing stuff at middle or end
            //if new is greater than current
            else{
          puts("here4");
                    previous->next = new;
                    new->next = current;
            }
    }
    return head;
}
//this function creates a new "node" for the list, returns pointer
car* createCar(char* model, char* color, int year){

    car *newCar = malloc(sizeof(car));
    newCar->color = malloc(sizeof(char)*MAX_MODEL);
    newCar->model = malloc(sizeof(char)*MAX_MODEL);

    strcpy(newCar->model,model);
    strcpy(newCar->color,color);
    newCar->year = year;
    newCar->next = NULL;

    return newCar;
 }
//this function prints out all of things in linked list
void printCars(car* head){

    if(head == NULL)
            printf("List is empty\n");

    else{
            printf("The list of cars in inventory are:\n");
            while(head!=NULL){
            printf("%-5d %-25s %-13s",head->year,head->model,head->color);
            printf("\n");
            head = head->next;
            }
    }
}

该程序的目的是读入一个文件,其中包含汽车的型号名称、颜色名称和年份。读入后,将按照汽车型号升序放入链表中。这是正在读取的文件:

Tesla S|royal|2015|
GMC Yukon|white|2005|
Dodge Charger|lime|2010|
Honda Civic|cobalt|1996|
Nissan Titan|saddlewood|2008|
Chevrolet Silverado|saddlewood|1999|
Ford Focus|lime|2000|
Toyota Tacoma|gunmetal|2009|
Tesla X|black|2016|
Nissan Maxima|white|2013|
Ford Explorer|forest|1996|
Chevrolet Corvette|cherry|1982|
Tesla 3|cherry|2017|
Nissan 370Z|royal|2011|
Ford F150|cherry|2006|
Honda Accord|white|2004|
Mitsubishi Eclipse|black|2002|
Toyota Tundra|cobalt|2017|
Dodge Challenger|lemon|1970|
Chevrolet Camaro|black|1966|

将“./a.out cars.txt”放入命令提示符后,输出为

here?
here2
here2.5
Segmentation fault

由于我的 puts 语句,我知道 seg 错误发生在我的 while 循环中的“insertInSortedOrder”函数中的某处。任何有关使此功能正常工作的帮助将不胜感激,谢谢

好的,我已经将插入函数更改为:

car* insertInSortedOrder(car* head, char* model, char* color, int year){

    //if list is emppty
    if(head == NULL){
            head = createCar(model,color,year);
    }
    else{
            car *new = createCar(model,color,year);
            car *current,*previous;
            current = head;
            previous = NULL;
            //compares new car model to next model, if  next is greater than new, move onto next pair
            while( strcmp(new->model,current->model)  <  0){
                    //if current is only node in list or end of list
                    if(current->next == NULL){
                            current->next = new;
                            return head;
                    }
                    else{
                            //move forward to compare new
                            previous = current;
                            current = current->next;
                    }
            }
            //when new is greater than current, put new on top of it
            previous = new;
            previous->next = current;
    }
    return head;
}

现在打印出来了:

The list of cars in inventory are:
2015  Tesla S                   royal
2005  GMC Yukon                 white
2010  Dodge Charger             lime 
1999  Chevrolet Silverado       saddlewood
1982  Chevrolet Corvette        cherry
1966  Chevrolet Camaro          black

所以耶!没有更多的段错误,但现在我认为我只是没有好的算法

【问题讨论】:

  • 1) char *readLine= malloc(sizeof(car)*MAX_MODEL); --> char *readLine= malloc(sizeof(car)*MAX_LINE);
  • 2) while(strcmp(new-&gt;model, current-&gt;model) &lt; 0){ previous = current; current = current-&gt;next; } :在第二次循环中 currentNULL。所以NULL-&gt;model 发生了seg-fault。
  • 还是同样的错误,我认为读取信息没有问题,因为我在 creatCar 函数中放置了一个 printf 函数来打印新节点中的数据,并将完整列表打印出来
  • 您是否正在使用Valgrind 可用的平台?如果是这样,请使用它。它将非常简洁地报告您的代码在哪里滥用内存。 (请记住在启用调试的情况下进行编译。在 Unix 上,这意味着在编译到对象和链接时都使用-g 选项。)您已经确定了崩溃发生的位置。正如@BLUEPIXY 所说,您需要保护循环不访问空指针,因此while 条件需要更像while (current != NULL &amp;&amp; strcmp(new-&gt;model, current-&gt;model) &lt; 0) { … }。崩溃通常与取消引用 NULL 相关。
  • 编写代码时,尽可能独立开发新功能。在这种情况下,请先使用int 列表进行排序顺序插入,然后再尝试处理如此复杂的货物。

标签: c linked-list nodes


【解决方案1】:

在分析了你的函数insertInSortedOrder()并阅读了@JonathanLeffler的警告后,我已经定位了你的排序列表中缺少项目的问题。

错误在'new is greater than current'的情况下

  • 无条件覆盖previous 指针

使用代码previous = new;而不检查previous是否指向一个节点将直接用新项目覆盖列表的一部分。

  • previous == NULL 时不会更改 head

previous == NULL 时,new 项应替换head

使用以下代码:

if (previous==NULL) {
    // new becomes the first node
    new->next = head;
    head = new;
}
else {
    // new is inserted between previous and current
    new->next = previous->next;
    previous->next = new;
}

代替代码:

previous = newitem;
previous->next = current;

【讨论】:

  • 一种更简单的形式使用指针到指针,只需要一个变量并且计算大约 5 行代码。
猜你喜欢
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 2020-05-11
  • 2019-12-05
  • 1970-01-01
  • 1970-01-01
  • 2016-07-05
  • 2019-07-28
相关资源
最近更新 更多