节点删除但不更新

时间:2015-04-17 15:21:52

标签: c linked-list nodes updates

我正在制作数组中包含的节点的链接列表。虽然这可能没有意义,但即使节点是物理顺序,因为它们在一个数组中,它们按照“链接”字段的值按逻辑顺序排列。

我创建了一个库,以便利用链表及其相关功能。可以把它想象成Java中的LinkedList类的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文件的更新部分无法正常工作。

作为一个快速概述,我评论了下面的“更新”片段与每条指令的作用

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特定的编译器之间存在一些差异。

1 个答案:

答案 0 :(得分:1)

问题在于

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;
}

返回匹配前的值的索引。为了获得匹配的节点,我必须引用找到的节点的链接。因此,更新选项变为:

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