我无法从链表中删除所有节点
I'm unable to delete all nodes from a linked list
我正在做一个学校项目,这是关于用单链表做的事情。我现在被困了几个小时,我真的不知道该怎么办。基本上,我的任务是从链表中删除节点。
这是我目前存储在节点中的内容:
1. Jozef Maly 7502110011 1178.88
2. Maria Krasna 6251034526 1636.90
3. Milan Vesely 9512157831 1835.20
4. asd fgh 9862111680 2000.00
5. lol pop 9862111680 2000.00
这是我目前的结果:
Deleted 2 nodes. //not really
1. Jozef Maly muz 11.02.1975 1178.88
2. Maria Krasna zena 03.01.1962 1636.90
3. Milan Vesely muz 15.12.1995 1835.20
4. lol pop zena 11.12.1998 2000.00
我的结果应该是这样的:
Deleted 2 nodes.
1. Jozef Maly 7502110011 1178.88
2. Maria Krasna 6251034526 1636.90
3. Milan Vesely 9512157831 1835.20
这是我的代码:
void overRC(struct list *z) {
int arr[10], notvalidarr[1000];
int notvalid = 0, x = 0, i = 0, j = 0, k = 0, day, month, year, number;
int len = length(z); //this function returns the number of nodes
struct data *temp;
temp = z->first; //z -> first is the head
while (temp != NULL) {
i++;
number = temp->ID / 10000;
for (int j = 0; j < 6; j++) {
arr[j] = number % 10;
number /= 10;
}
day = 10 * arr[1] + arr[0];
month = 10 * arr[3] + arr[2];
year = 1900 + 10 * arr[5] + arr[4];
if (temp->ID % 11 != 0 || month <= 0 || month > 12 && month < 51 || month > 62 || month == 2 && day > 29 || month <= 7 && month % 2 == 1 && day > 31 || || month <= 7 && month % 2 == 0 && day > 30 || month >= 8 && month % 2 == 0 && day > 31 || month >= 8 && month % 2 == 1 && day > 30) {
notvalidarr[x++] = i; //i store the positions in this array: 4, 5
}
day = 0;
month = 0;
year = 0;
temp = temp->next;
}
for (j = 0; j < x; j++) {
deleteNode(&z->first, notvalidarr[j]);
notvalid++;
}
printf("Deleted %d nodes\n", notvalid); //it says it deleted 2
}
void deleteNode(struct data **head_ref, int position) {
if (*head_ref == NULL)
return;
struct data *temp = *head_ref;
if (position == 1) {
*head_ref = temp->next;
free(temp);
return;
}
for (int i = 1; i < position - 1; i++)
temp = temp->next;
if (temp == NULL || temp->next == NULL)
return;
struct data *next = temp->next->next;
free(temp->next);
temp->next = next;
}
代码无法编译,因为 notvalidarr
的测试有一个语法错误:||
followed be ||
。您应该使用月中天数的最大值数组来简化此测试。
如果 position
太大,deleteNode
函数中可能存在问题,因为您在计算 temp = temp->next;
[ 之前没有测试 temp
是否为 null =19=]
调用deleteNode
的代码还有一个问题:要移除的节点数组应该从最高位置到最低位置扫描,否则移除节点后位置不正确。
这是更正和简化的版本:
void overRC(struct list *z) {
static int mdays[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int deleted = 0;
struct data **linkp = &z->first;
struct data *temp;
while ((temp = *linkp) != NULL) {
int number = temp->ID / 10000;
int day = number % 100;
int month = number / 100 % 100;
int year = 1900 + number / 10000 % 100;
if (temp->ID % 11 != 0 ||
month <= 0 || month > 12 ||
day <= 0 || day > mdays[month] ||
(month == 2 && day == 29 && (year == 1900 || year % 4 != 0))) {
*linkp = temp->next;
free(temp);
deleted++;
} else {
linkp = &temp->next;
}
}
printf("Deleted %d nodes\n", deleted);
}
我正在做一个学校项目,这是关于用单链表做的事情。我现在被困了几个小时,我真的不知道该怎么办。基本上,我的任务是从链表中删除节点。
这是我目前存储在节点中的内容:
1. Jozef Maly 7502110011 1178.88
2. Maria Krasna 6251034526 1636.90
3. Milan Vesely 9512157831 1835.20
4. asd fgh 9862111680 2000.00
5. lol pop 9862111680 2000.00
这是我目前的结果:
Deleted 2 nodes. //not really
1. Jozef Maly muz 11.02.1975 1178.88
2. Maria Krasna zena 03.01.1962 1636.90
3. Milan Vesely muz 15.12.1995 1835.20
4. lol pop zena 11.12.1998 2000.00
我的结果应该是这样的:
Deleted 2 nodes.
1. Jozef Maly 7502110011 1178.88
2. Maria Krasna 6251034526 1636.90
3. Milan Vesely 9512157831 1835.20
这是我的代码:
void overRC(struct list *z) {
int arr[10], notvalidarr[1000];
int notvalid = 0, x = 0, i = 0, j = 0, k = 0, day, month, year, number;
int len = length(z); //this function returns the number of nodes
struct data *temp;
temp = z->first; //z -> first is the head
while (temp != NULL) {
i++;
number = temp->ID / 10000;
for (int j = 0; j < 6; j++) {
arr[j] = number % 10;
number /= 10;
}
day = 10 * arr[1] + arr[0];
month = 10 * arr[3] + arr[2];
year = 1900 + 10 * arr[5] + arr[4];
if (temp->ID % 11 != 0 || month <= 0 || month > 12 && month < 51 || month > 62 || month == 2 && day > 29 || month <= 7 && month % 2 == 1 && day > 31 || || month <= 7 && month % 2 == 0 && day > 30 || month >= 8 && month % 2 == 0 && day > 31 || month >= 8 && month % 2 == 1 && day > 30) {
notvalidarr[x++] = i; //i store the positions in this array: 4, 5
}
day = 0;
month = 0;
year = 0;
temp = temp->next;
}
for (j = 0; j < x; j++) {
deleteNode(&z->first, notvalidarr[j]);
notvalid++;
}
printf("Deleted %d nodes\n", notvalid); //it says it deleted 2
}
void deleteNode(struct data **head_ref, int position) {
if (*head_ref == NULL)
return;
struct data *temp = *head_ref;
if (position == 1) {
*head_ref = temp->next;
free(temp);
return;
}
for (int i = 1; i < position - 1; i++)
temp = temp->next;
if (temp == NULL || temp->next == NULL)
return;
struct data *next = temp->next->next;
free(temp->next);
temp->next = next;
}
代码无法编译,因为 notvalidarr
的测试有一个语法错误:||
followed be ||
。您应该使用月中天数的最大值数组来简化此测试。
如果 position
太大,deleteNode
函数中可能存在问题,因为您在计算 temp = temp->next;
[ 之前没有测试 temp
是否为 null =19=]
调用deleteNode
的代码还有一个问题:要移除的节点数组应该从最高位置到最低位置扫描,否则移除节点后位置不正确。
这是更正和简化的版本:
void overRC(struct list *z) {
static int mdays[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int deleted = 0;
struct data **linkp = &z->first;
struct data *temp;
while ((temp = *linkp) != NULL) {
int number = temp->ID / 10000;
int day = number % 100;
int month = number / 100 % 100;
int year = 1900 + number / 10000 % 100;
if (temp->ID % 11 != 0 ||
month <= 0 || month > 12 ||
day <= 0 || day > mdays[month] ||
(month == 2 && day == 29 && (year == 1900 || year % 4 != 0))) {
*linkp = temp->next;
free(temp);
deleted++;
} else {
linkp = &temp->next;
}
}
printf("Deleted %d nodes\n", deleted);
}