gpt4 book ai didi

c - 递归反向链接列表

转载 作者:行者123 更新时间:2023-11-30 15:23:21 26 4
gpt4 key购买 nike

我不明白为什么我的代码会崩溃。一切正常,除了当我尝试反转链表时。它“停止工作”。 (这个函数;void reverseList(struct ProduceItem** inHead))有什么想法吗?我已经坚持这个问题有一段时间了。我认为问题可能是它在某些地方没有读取 NULL,但我无法弄清楚。

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

struct produceItem{
char produce[20];
char type[20];
char soldBy[20];
float price;
int quantityInStock;
struct produceItem *next;
};

struct produceItem* append(struct produceItem *inHead, char *nextProduce, char *nextType, char *nextSoldBy, char *nextPrice, char *nextQuantityInStock){

struct produceItem *temp;
temp =(struct produceItem *)malloc(sizeof(struct produceItem));
strcpy(temp->produce, nextProduce);
strcpy(temp->type, nextType);
strcpy(temp->soldBy, nextSoldBy);
temp->price = atof(nextPrice);
temp->quantityInStock = atoi(nextQuantityInStock);

if(inHead == NULL){
inHead = temp;
temp->next = NULL;
}

else{
temp->next = inHead;
inHead = temp;
}
return inHead;
}

struct produceItem* readData(struct produceItem *inHead){
const char comma[2] = ",";
char *produceTemp;
char *typeTemp;
char *soldByTemp;
char *priceTemp;
char *quantityInStockTemp;

char dataLine[100];
char fileName[] = "AssignmentTwoInput.txt";
FILE *inputFile;

printf("\nFile %s has been read.\n\n", fileName);
inputFile = fopen(fileName, "r");

if( inputFile == NULL){
printf("%sList Does not exist\n", fileName);
return;
}

while((fgets(dataLine, 100, inputFile)) != NULL){
produceTemp = strtok(dataLine, comma);
typeTemp = strtok(NULL, comma);
soldByTemp = strtok(NULL, comma);
priceTemp = strtok(NULL, comma);
quantityInStockTemp = strtok(NULL, comma);
inHead = append(inHead, produceTemp,typeTemp,soldByTemp,priceTemp,quantityInStockTemp);
}
fclose(inputFile);
return inHead;
}



void display(struct produceItem *inHead){

int i = 1;
if(inHead == NULL){
printf("List does not exist.\n");
return;
}
printf("=========================================================================\n");
printf("Item # Produce Type Sold By Price In Stock\n");
printf("==========================================================================\n");

for(i=1; i<27; i++){
//while(inHead != NULL){
printf("\n%5d", i);
printf(" %-12s ", inHead->produce);
printf("%-16s ", inHead->type);
printf("%-16s ", inHead->soldBy);
printf("%3.2f ", inHead->price);
printf("%8d", inHead->quantityInStock);
inHead = inHead->next;
//i++;
}
printf("\n\n");
}

exportData(struct produceItem *n){
char fileName[] = "AssignmentTwoOutput.txt";
FILE *exportFile;
int i =1;

if(n == NULL){
printf("List does not exist.\n");
return;
}

exportFile = fopen(fileName, "w");
//printf("hi");
fprintf(exportFile,"================================================================\n");
//printf("hi");
fprintf(exportFile,"Item# Produce Type Sold By Price In Stock\n");
fprintf(exportFile,"================================================================\n");

for(i=1; i<27; i++){
//while(n->next != NULL){
//printf("hi");
fprintf(exportFile,"\n%3d", i);
fprintf(exportFile," %-12s ", n->produce);
fprintf(exportFile,"%-15s ", n->type);
fprintf(exportFile,"%-15s ", n->soldBy);
fprintf(exportFile,"%3.2f ", n->price);
fprintf(exportFile,"%8d", n->quantityInStock);
n = n->next;
}
printf("\nYour data has been written to AssignmentTwoOutput.txt, thank you.\n\n");
fclose(exportFile);
}

//void recursiveReverse(struct node** head_ref)
//{
//struct node* first;
// struct node* rest;

/* empty list */
// if (*head_ref == NULL)
//return;

/* suppose first = {1, 2, 3}, rest = {2, 3} */
//first = *head_ref;
//rest = first->next;

/* List has only one node */
//if (rest == NULL)
//return;

/* reverse the rest list and put the first element at the end */
//recursiveReverse(&rest);
//first->next->next = first;

/* tricky step -- see the diagram */
//first->next = NULL;

/* fix the head pointer */
//*head_ref = rest;
//}

void reverseList(struct produceItem** inHead){

//printf("1");
struct produceItem* first;
struct produceItem* follow;
//printf("2");

if (*inHead==NULL){
// printf("3");
printf("List does not exist.\n");
return;}

first = *inHead;
//printf("4");
follow = first->next;

if(follow==NULL)
//printf("5");
return;

reverseList(&follow);
first->next->next = first;
first->next = NULL;
*inHead = follow;
}

int main (void){
int choice;
struct produceItem *head;

while(1){
printf("List of Operations\n");
printf("===============\n");
printf("1. Stock Produce Department\n");
printf("2. Display Produce Inventory\n");
printf("3. Reverse Order of Produce Inventory\n");
printf("4. Export Produce Inventory\n");
printf("5. Exit\n");

printf("Enter you choice: ");
scanf("%d", &choice);

if(choice <= 0 || choice > 5){
printf("Enter a valid response please: \n");
exit(0);
}

switch(choice){
case 1:
//reading from thefile
head = readData(head);
break;
case 2:
//displays the list
display(head);
break;

case 3:
//reverse the list
reverseList(&head);
break;

case 4:
exportData(head);
break;

case 5:
//Exits the operation
printf("Exiting, Thank you.");
exit(0);
break;
}
}
}

最佳答案

在此递归函数中:

void reverseList(struct produceItem** inHead){

//printf("1");
struct produceItem* first;
struct produceItem* follow;
//printf("2");

if (*inHead==NULL){
// printf("3");
printf("List does not exist.\n");
return;}

first = *inHead;
//printf("4");
follow = first->next;

if(follow==NULL)
//printf("5");
return;

reverseList(&follow);
first->next->next = first;
first->next = NULL;
*inHead = follow;
}

此函数将在列表中递归运行。

好的,让我们看看你的代码:

  1. 2 个局部变量(实际上什么也不做)
  2. 如果输入为空则退出的代码(主要是为了安全)
  3. 您将局部变量设置为当前和下一个节点。
  4. 如果这是列表中的最后一个节点,则退出代码。
  5. 您递归地调用您的函数。

请注意,在这个阶段实际上什么都没有发生。这意味着您的处理(函数末尾的行)将以列表的相反顺序进行。从后到前。这似乎适合您想做的事情。

下一行:

first->next->next = first;

这似乎是正确的,因为它将设置下一个“后续”节点指向此节点。就像更改列表中下一个指针的方向一样。

现在你有这一行:

first->next = NULL;

请记住,我们说过您对节点的“处理”将以相反的顺序进行。因此,您将有效地一一将所有 next 指针设置为 NULL。我认为这会完全断开您的队列?

我理解的最后一行只是为了让您能够找到队列的新头指针,这看起来很好。

顺便说一句,使用递归进行这种算法通常是一个坏主意。因为如果列表变长,很容易导致堆栈溢出问题。此外,如果由于某种原因你的列表有问题并且是循环的,那么很难检测到它并且不会引起问题。此外,通常就性能而言,这种类型的递归算法会比正确的循环实现慢。

“反转”列表的伪代码:

reverseList(** head)
{
current = head
prev = null
next = null
int i = 0;
while (current)
{
next = current->next;

current->next = prev;

prev = current;
current = next;


i++;
if (i > MAX) reportError();
}
head = prev;
}

关于c - 递归反向链接列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28825092/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com