节点删除但不更新
Node Deleting But Not Updating
我正在制作包含在数组中的节点的链表。虽然这可能没有意义,但即使节点是按物理顺序排列的(因为它们在数组中),它们也是按 "link" 字段的值按逻辑顺序排列的。
为了使用链表及其相关函数,我创建了一个库。将其视为 Java 中 LinkedList class 的 C 等价物。因此,每个节点都可以通过 void 指针引用任何类型的数据。
这是linkedlist.h头文件:
#define listSize 100
struct Node
{
union{
void *dataPtr;
int countr;
}dataItem;
int link;
};
void initializeList(struct Node[], int);
int findEmptyNode(struct Node[], int);
void attachNode(struct Node[], int, int);
void displayList(struct Node[], int, void(*)(void*));
void insertNode(struct Node[], int, int, int);
int search2Insert(struct Node[], int, int);
void deleteNode(struct Node[], int, int);
int search2delete(struct Node[], int, int);
int searchList(struct Node[], int, int, int(*)(void*, void*), int);
void initializeList(struct Node LL[], int Head)
{
LL[Head].link = -5;
LL[Head].dataItem.countr = 0;
for (int x = 1; x < listSize; x++)
LL[x].link = -1;
}
int findEmptyNode(struct Node LL[], int head)
{
int temp = head;
while (LL[temp].link != -1)
temp++;
return temp;
}
void attachNode(struct Node LL[], int Header, int index)
{
int temp = Header;
while (LL[temp].link != -5)
temp = LL[temp].link;
LL[index].link = LL[temp].link;
LL[temp].link = index;
LL[Header].dataItem.countr++;
}
void displayList(struct Node LL[], int Head, void(*ptr)(void*))
{
int temp = LL[Head].link;
while (temp != -5)
{
ptr(LL[temp].dataItem.dataPtr);
temp = LL[temp].link;
}
}
void insertNode(struct Node LL[], int current, int index, int head)
{
LL[index].link = LL[current].link;
LL[current].link = index;
LL[head].dataItem.countr++;
}
void deleteNode(struct Node LL[], int Head, int current)
{
int oldNode = LL[current].link;
LL[current].link = LL[oldNode].link;
LL[oldNode].link = -1;
LL[Head].dataItem.countr--;
}
int searchList(struct Node LL[], int head, int ndex, int(*ptr)(void*, void*), int relation)
{
int temp = head;
int nodeRef, found = 0;
while (LL[temp].link != -5 && found == 0)
{
nodeRef = LL[temp].link;
if (ptr(LL[nodeRef].dataItem.dataPtr, LL[ndex].dataItem.dataPtr) == relation)
found = 1;
else
temp = LL[temp].link;
}
return temp;
}
我正在使用这个头文件来保存产品结构的链接列表。我遇到的问题是我的特定于应用程序的 c 文件的更新部分不起作用。
作为快速概览,我在下面的 "update" 片段中评论了每条指令的作用
if (choice == 4)
{
newIndex = findEmptyNode(LinkedList, Header);// this retrieves the index of an empty node
printf("\nUpdate item by searching for it by product code\n");
getProdCode(&LinkedList[newIndex]);// this fills out a "template" with the product structure that contains the "product code" you're looking for
current = searchList(LinkedList, Header, newIndex, comparInt, 0);//this takes that new template node and compares it against all other nodes until it finds on with the same product structure and returns the index of that node
readData(&LinkedList[current]);// this takes that index and fills out the product structure that is attached to the void pointer in that node
}
我意识到这有点抽象,所以为了进一步参考,这是 c 文件:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linkedlist.h"
#define listSize 100
typedef struct Product{
int code;//product code – integer
char name[31];//product name – 30 characters
int quantity;//quantity on hand – integer
double cost;//unit cost – double
double price;//retail price – double(30 % markup from unit cost)
char loc[7];//location code – 6 characters
} product;
void addFromFile(struct Node[], int);
int Display(struct Node[], int);
void readData(struct Node*);
void getProdCode(struct Node*);
void displayData(void *);
int comparInt(void *D1, void *D2);
void main()
{
struct Node LinkedList[listSize];
int Header = 0;
int newIndex, current;
int choice;
void(*stuff)(void *) = displayData;
int(*item)(void*, void*);
initializeList(LinkedList, Header);
//displayList(LinkedList, Header, stuff);
choice = Display(LinkedList, Header);
addFromFile(LinkedList, Header);
while (choice != 0)
{
if (choice == 1)
{
newIndex = findEmptyNode(LinkedList, Header);
readData(&LinkedList[newIndex]);
current = searchList(LinkedList, Header, newIndex, comparInt, 1);
insertNode(LinkedList, current, newIndex, Header);
}
if (choice == 2)
{
printf("\n%7s%30s%10s%7.2s%10.2s%10s", "CODE", "NAME", "QUANTITY", "COST", "PRICE", "LOC");
displayList(LinkedList, Header, stuff);
}
if (choice == 3)
{
newIndex = findEmptyNode(LinkedList, Header);
printf("\nDelete item by searching for it by product code\n");
getProdCode(&LinkedList[newIndex]);
current = searchList(LinkedList, Header, newIndex, comparInt, 0);
deleteNode(LinkedList, Header, current);
}
if (choice == 4)
{
newIndex = findEmptyNode(LinkedList, Header);
printf("\nUpdate item by searching for it by product code\n");
getProdCode(&LinkedList[newIndex]);
current = searchList(LinkedList, Header, newIndex, comparInt, 0);
readData(&LinkedList[current]);
}
if (choice != 1 && choice != 2 && choice != 3 && choice != 4)
{
printf("\n\nThe value you entered is not a valid choice\n\tplease try again\n\n");
}
choice = Display(LinkedList, Header);
}
printf("\n\n\t\tTHE APPLICATION HAS TERMINATED\n\n\n ");
}
int Display(struct Node LL[], int Head)
{
int choice;
printf("\n\nProduct Catalog\n");
//printf("there are %d items in the list\n", LL[Head].dataItem.countr);
printf("enter a value to indicate what you would like to do\n ");
printf("a value of zero entered will terminate the application\n");
printf(" a value of 1 will add an item to the list\n");
printf(" a value of 2 will display the contents of the list\n");
printf(" a value of 3 will delete an item from the list\n");
printf(" a value of 4 will update the item");
printf(" your choice is >> ");
/*fflush(stdin);*/
scanf("%d", &choice);
return choice;
}
void addFromFile(struct Node LL[], int Head){
//int i = 0;
int newIndex;
int current;
FILE *fp = fopen("product.txt", "r");
product *ptr = (product *)malloc(sizeof(struct Product));
struct Node *node;
while (EOF != fscanf(fp, "%d %30[^\n] %d %lf %6[^\n]", &(ptr->code), ptr->name, &ptr->quantity, &ptr->cost, &ptr->loc))
{
ptr->price = (ptr->cost/0.7);//calculate the cost
newIndex = findEmptyNode(LL, Head);
LL[newIndex].dataItem.dataPtr = ptr;
current = searchList(LL, Head, newIndex, comparInt, 1);
insertNode(LL, current, newIndex, Head);
//printf("\n%s\n", ((product*)(node->dataItem.dataPtr))->name);
ptr = (product *)malloc(sizeof(struct Product));
}
}
void readData(struct Node *node)
{
product *ptr = (product *)malloc(sizeof(struct Product));
printf("Product Code: ");
scanf("%d", &(ptr->code));
printf("Name: ");
fflush(stdin);
scanf("%[^\n]", ptr->name);
printf("Quantity: ");
scanf("%d", &(ptr->quantity));
printf("Cost: ");
scanf("%lf", &(ptr->cost));
ptr->price = (ptr->cost/0.7);
printf("Location: ");
fflush(stdin);
scanf("%[^\n]", ptr->loc);
node->dataItem.dataPtr = ptr;
}
void getProdCode(struct Node *node){
product *ptr = (product *)malloc(sizeof(struct Product));
printf("Product Code: ");
scanf("%d", &(ptr->code));
node->dataItem.dataPtr = ptr;
}
void displayData(void *ptr)
{
product* test = (product *)(ptr);
printf("\n%7d%30s%10d%7.2f%10.2f%10s", test->code, test->name, test->quantity, test->cost, test->price, test->loc);
//printf("\n\n");
}
int comparInt(void *D1, void *D2)
{
int temp;
if (((product*)D1)->code > ((product*)D2)->code)
temp = 1;
else
if (((product*)D1)->code < ((product*)D2)->code)
temp = -1;
else
temp = 0;
return temp;
}
而引用的"product.txt"文件可以是found here
我对此有点困惑,因为在删除节点选项中搜索的相同关系正在更新节点选项中搜索;但是,删除节点选项有效,而更新节点选项无效。
我是否忽略了一些关键组件?任何建议将不胜感激。
免责声明: 这是在 Microsoft Visual Studios 2012 中编译的。我知道 gcc 和特定于 VS 的编译器之间存在一些差异。
问题是
int searchList(struct Node LL[], int head, int ndex, int(*ptr)(void*, void*), int relation)
{
int temp = head;
int nodeRef, found = 0;
while (LL[temp].link != -5 && found == 0)
{
nodeRef = LL[temp].link;
if (ptr(LL[nodeRef].dataItem.dataPtr, LL[ndex].dataItem.dataPtr) == relation)
found = 1;
else
temp = LL[temp].link;
}
return temp;
}
返回匹配前值的索引。为了获得匹配的节点,我必须引用找到的节点的 link 。所以更新的选项变成了:
newIndex = findEmptyNode(LinkedList, Header);
printf("\nDelete item by searching for it by product code\n");
getProdCode(&LinkedList[newIndex]);
current = searchList(LinkedList, Header, newIndex, comparInt, 0);
readData(&LinkedList[LinkedList[current].link]);//this is what changed
我正在制作包含在数组中的节点的链表。虽然这可能没有意义,但即使节点是按物理顺序排列的(因为它们在数组中),它们也是按 "link" 字段的值按逻辑顺序排列的。
为了使用链表及其相关函数,我创建了一个库。将其视为 Java 中 LinkedList class 的 C 等价物。因此,每个节点都可以通过 void 指针引用任何类型的数据。
这是linkedlist.h头文件:
#define listSize 100
struct Node
{
union{
void *dataPtr;
int countr;
}dataItem;
int link;
};
void initializeList(struct Node[], int);
int findEmptyNode(struct Node[], int);
void attachNode(struct Node[], int, int);
void displayList(struct Node[], int, void(*)(void*));
void insertNode(struct Node[], int, int, int);
int search2Insert(struct Node[], int, int);
void deleteNode(struct Node[], int, int);
int search2delete(struct Node[], int, int);
int searchList(struct Node[], int, int, int(*)(void*, void*), int);
void initializeList(struct Node LL[], int Head)
{
LL[Head].link = -5;
LL[Head].dataItem.countr = 0;
for (int x = 1; x < listSize; x++)
LL[x].link = -1;
}
int findEmptyNode(struct Node LL[], int head)
{
int temp = head;
while (LL[temp].link != -1)
temp++;
return temp;
}
void attachNode(struct Node LL[], int Header, int index)
{
int temp = Header;
while (LL[temp].link != -5)
temp = LL[temp].link;
LL[index].link = LL[temp].link;
LL[temp].link = index;
LL[Header].dataItem.countr++;
}
void displayList(struct Node LL[], int Head, void(*ptr)(void*))
{
int temp = LL[Head].link;
while (temp != -5)
{
ptr(LL[temp].dataItem.dataPtr);
temp = LL[temp].link;
}
}
void insertNode(struct Node LL[], int current, int index, int head)
{
LL[index].link = LL[current].link;
LL[current].link = index;
LL[head].dataItem.countr++;
}
void deleteNode(struct Node LL[], int Head, int current)
{
int oldNode = LL[current].link;
LL[current].link = LL[oldNode].link;
LL[oldNode].link = -1;
LL[Head].dataItem.countr--;
}
int searchList(struct Node LL[], int head, int ndex, int(*ptr)(void*, void*), int relation)
{
int temp = head;
int nodeRef, found = 0;
while (LL[temp].link != -5 && found == 0)
{
nodeRef = LL[temp].link;
if (ptr(LL[nodeRef].dataItem.dataPtr, LL[ndex].dataItem.dataPtr) == relation)
found = 1;
else
temp = LL[temp].link;
}
return temp;
}
我正在使用这个头文件来保存产品结构的链接列表。我遇到的问题是我的特定于应用程序的 c 文件的更新部分不起作用。
作为快速概览,我在下面的 "update" 片段中评论了每条指令的作用
if (choice == 4)
{
newIndex = findEmptyNode(LinkedList, Header);// this retrieves the index of an empty node
printf("\nUpdate item by searching for it by product code\n");
getProdCode(&LinkedList[newIndex]);// this fills out a "template" with the product structure that contains the "product code" you're looking for
current = searchList(LinkedList, Header, newIndex, comparInt, 0);//this takes that new template node and compares it against all other nodes until it finds on with the same product structure and returns the index of that node
readData(&LinkedList[current]);// this takes that index and fills out the product structure that is attached to the void pointer in that node
}
我意识到这有点抽象,所以为了进一步参考,这是 c 文件:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linkedlist.h"
#define listSize 100
typedef struct Product{
int code;//product code – integer
char name[31];//product name – 30 characters
int quantity;//quantity on hand – integer
double cost;//unit cost – double
double price;//retail price – double(30 % markup from unit cost)
char loc[7];//location code – 6 characters
} product;
void addFromFile(struct Node[], int);
int Display(struct Node[], int);
void readData(struct Node*);
void getProdCode(struct Node*);
void displayData(void *);
int comparInt(void *D1, void *D2);
void main()
{
struct Node LinkedList[listSize];
int Header = 0;
int newIndex, current;
int choice;
void(*stuff)(void *) = displayData;
int(*item)(void*, void*);
initializeList(LinkedList, Header);
//displayList(LinkedList, Header, stuff);
choice = Display(LinkedList, Header);
addFromFile(LinkedList, Header);
while (choice != 0)
{
if (choice == 1)
{
newIndex = findEmptyNode(LinkedList, Header);
readData(&LinkedList[newIndex]);
current = searchList(LinkedList, Header, newIndex, comparInt, 1);
insertNode(LinkedList, current, newIndex, Header);
}
if (choice == 2)
{
printf("\n%7s%30s%10s%7.2s%10.2s%10s", "CODE", "NAME", "QUANTITY", "COST", "PRICE", "LOC");
displayList(LinkedList, Header, stuff);
}
if (choice == 3)
{
newIndex = findEmptyNode(LinkedList, Header);
printf("\nDelete item by searching for it by product code\n");
getProdCode(&LinkedList[newIndex]);
current = searchList(LinkedList, Header, newIndex, comparInt, 0);
deleteNode(LinkedList, Header, current);
}
if (choice == 4)
{
newIndex = findEmptyNode(LinkedList, Header);
printf("\nUpdate item by searching for it by product code\n");
getProdCode(&LinkedList[newIndex]);
current = searchList(LinkedList, Header, newIndex, comparInt, 0);
readData(&LinkedList[current]);
}
if (choice != 1 && choice != 2 && choice != 3 && choice != 4)
{
printf("\n\nThe value you entered is not a valid choice\n\tplease try again\n\n");
}
choice = Display(LinkedList, Header);
}
printf("\n\n\t\tTHE APPLICATION HAS TERMINATED\n\n\n ");
}
int Display(struct Node LL[], int Head)
{
int choice;
printf("\n\nProduct Catalog\n");
//printf("there are %d items in the list\n", LL[Head].dataItem.countr);
printf("enter a value to indicate what you would like to do\n ");
printf("a value of zero entered will terminate the application\n");
printf(" a value of 1 will add an item to the list\n");
printf(" a value of 2 will display the contents of the list\n");
printf(" a value of 3 will delete an item from the list\n");
printf(" a value of 4 will update the item");
printf(" your choice is >> ");
/*fflush(stdin);*/
scanf("%d", &choice);
return choice;
}
void addFromFile(struct Node LL[], int Head){
//int i = 0;
int newIndex;
int current;
FILE *fp = fopen("product.txt", "r");
product *ptr = (product *)malloc(sizeof(struct Product));
struct Node *node;
while (EOF != fscanf(fp, "%d %30[^\n] %d %lf %6[^\n]", &(ptr->code), ptr->name, &ptr->quantity, &ptr->cost, &ptr->loc))
{
ptr->price = (ptr->cost/0.7);//calculate the cost
newIndex = findEmptyNode(LL, Head);
LL[newIndex].dataItem.dataPtr = ptr;
current = searchList(LL, Head, newIndex, comparInt, 1);
insertNode(LL, current, newIndex, Head);
//printf("\n%s\n", ((product*)(node->dataItem.dataPtr))->name);
ptr = (product *)malloc(sizeof(struct Product));
}
}
void readData(struct Node *node)
{
product *ptr = (product *)malloc(sizeof(struct Product));
printf("Product Code: ");
scanf("%d", &(ptr->code));
printf("Name: ");
fflush(stdin);
scanf("%[^\n]", ptr->name);
printf("Quantity: ");
scanf("%d", &(ptr->quantity));
printf("Cost: ");
scanf("%lf", &(ptr->cost));
ptr->price = (ptr->cost/0.7);
printf("Location: ");
fflush(stdin);
scanf("%[^\n]", ptr->loc);
node->dataItem.dataPtr = ptr;
}
void getProdCode(struct Node *node){
product *ptr = (product *)malloc(sizeof(struct Product));
printf("Product Code: ");
scanf("%d", &(ptr->code));
node->dataItem.dataPtr = ptr;
}
void displayData(void *ptr)
{
product* test = (product *)(ptr);
printf("\n%7d%30s%10d%7.2f%10.2f%10s", test->code, test->name, test->quantity, test->cost, test->price, test->loc);
//printf("\n\n");
}
int comparInt(void *D1, void *D2)
{
int temp;
if (((product*)D1)->code > ((product*)D2)->code)
temp = 1;
else
if (((product*)D1)->code < ((product*)D2)->code)
temp = -1;
else
temp = 0;
return temp;
}
而引用的"product.txt"文件可以是found here
我对此有点困惑,因为在删除节点选项中搜索的相同关系正在更新节点选项中搜索;但是,删除节点选项有效,而更新节点选项无效。
我是否忽略了一些关键组件?任何建议将不胜感激。
免责声明: 这是在 Microsoft Visual Studios 2012 中编译的。我知道 gcc 和特定于 VS 的编译器之间存在一些差异。
问题是
int searchList(struct Node LL[], int head, int ndex, int(*ptr)(void*, void*), int relation)
{
int temp = head;
int nodeRef, found = 0;
while (LL[temp].link != -5 && found == 0)
{
nodeRef = LL[temp].link;
if (ptr(LL[nodeRef].dataItem.dataPtr, LL[ndex].dataItem.dataPtr) == relation)
found = 1;
else
temp = LL[temp].link;
}
return temp;
}
返回匹配前值的索引。为了获得匹配的节点,我必须引用找到的节点的 link 。所以更新的选项变成了:
newIndex = findEmptyNode(LinkedList, Header);
printf("\nDelete item by searching for it by product code\n");
getProdCode(&LinkedList[newIndex]);
current = searchList(LinkedList, Header, newIndex, comparInt, 0);
readData(&LinkedList[LinkedList[current].link]);//this is what changed