节点删除但不更新

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