链接列表程序未正确更新

时间:2014-10-14 16:45:44

标签: c linked-list xdebug

我创建了一个读取包含整数的文本文件的程序。它应该读取这些整数,然后创建它们的链接列表。但是,即使只是尾部,我的程序的头指针也会不断更新。有人知道为什么吗?输入文件可以是由空格或换行符分隔的整数。这是我的代码:

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

/*THIS IS THE BASIC NAME STRUCTURE. IT CONTAINS A FIRST AND LAST NAME VARIABLE*/
struct number {
    int * number;          //number
};
/*THIS IS THE BASIC NAME NODE STRUCTURE. IT CONTAINS A NAME STRUCT AS WELL AS STRUCT NAMENODES TO PREVIOUS AND NEXT NODES*/

struct numberNode {
    struct number number;          //name stuct call

    struct numberNode *pNext;    //pointer to next node
    struct numberNode *pPrev;    //pointer to previous node

};

/*THESE NAMENODES WILL BE USED THROUGHOUT THE PRGRAM AS THE HEAD AND TAIL OF THE PROGRAM*/
struct numberNode *pHead = NULL, *pTail=NULL;



/*THIS PROGRAM READS A FILE AND PLACES THE NAMES INTO LINKED LIST*/
void insert_end(int *num)

{

    struct numberNode *var = NULL,*temp = NULL;                   //set temp nodes

    var=(struct numberNode *)malloc(sizeof(struct numberNode));     //allocate memory for new node

    var->number.number= num;                         //set number of number stored in node





    if(pHead==NULL){                                            //check if it is the head


        pHead=var;                                              //set node to head b/c of first element

        pHead->pPrev=NULL;                                      //set node next and prev to null

        pHead->pNext=NULL;

        pTail=pHead;                                            //make head and tail the same

    }else{

        pTail=pHead;                                        //set tail to head

        while(pTail!=NULL)                                  //while tail is not NULL

        {

            temp=pTail;                                     //set temp node to tail pointer

            pTail=pTail->pNext;                             //traverse the linked list

        }

        pTail=var;                                          //set ptail to correct node

        temp->pNext=pTail;                                  //set the temps next to tail

        pTail->pPrev=temp;                                  //set the tail's previous pointer to temp

        pTail->pNext=NULL;                                  //set tail next to NULL

    }


}



/*FUNCTION FOR DISPLAYING LINKED LIST DATA*/
void display(){
    struct numberNode *node;
    node=pHead;
    printf("Displaying Linked List \n ************************************** \n");
    while(node != NULL){
        printf("Number is %d\n", *node->number.number);
        node = node->pNext;
    }
    printf("List is terminated\n ************************************* \n");
}

void displayBackwards(){
    struct numberNode *node;
    node=pTail;
    printf("Displaying Linked List Backwards \n ************************************** \n");
    while(node != NULL){
        printf("Number is %d\n", *node->number.number);
        node = node->pPrev;
    }
    printf("List is terminated\n ************************************* \n");
}




/*DELETE NODE PASSED IN ARGUEMENT*/
void deleteNode(struct numberNode *node){
    if (node!= pHead){
        node->pPrev->pNext=node->pNext;
        node->pNext->pPrev=node->pPrev;
        node->pNext = NULL;
        free(node);
    }else{
        pHead->pNext = pHead;
        free(node);
    }
}

//SWITCH THE LOCATIONS OF THE TWO NODES PASSED AS ARGUEMENTS
void switchNodes(struct numberNode *leftNode, struct numberNode *rightNode){
    struct numberNode temp;
    temp = *leftNode;
    leftNode->number=rightNode->number;
    rightNode->number= temp.number;

}

/*ORGANIZE LINKED LIST IN ALPHABETICAL ORDER*/
void organizeInAscendingOrder(){
    struct numberNode *node = pHead;
    int length=0;
    while(node != NULL){
        node = node->pNext;
        length ++;
    }
    node = pHead;
    int index = 0, secondIndex = 0;
    for (index=0; index<length; index++){
        for (secondIndex=0; secondIndex<length-1; secondIndex++){
            if(node->number.number > node->pNext->number.number){
                switchNodes(node, node->pNext);
            }
            node=node->pNext;
        }
        node=pHead;
    }
}

/*PUSH NODE PASSED AS ARGUEMENT TO THE BACK*/
void pushToBack(struct numberNode *node){
    pTail->pNext = node;
    deleteNode(node);
}


int main() {


    char file[100];
    printf("Enter input file ");
    scanf("%s", file);
    FILE *in_file = fopen(file, "r");


    int number;

    char *buffer;



    while(fscanf(in_file,"%d", &number)!=EOF)

    {

        insert_end(&number);
    }

    display();

    organizeInAscendingOrder();

    display();

    displayBackwards();


}

3 个答案:

答案 0 :(得分:1)

你对数据结构有点混乱 - 你可以减少这个:

struct number {
    int * number;          //number
};
/*THIS IS THE BASIC NAME NODE STRUCTURE. IT CONTAINS A NAME STRUCT AS WELL AS STRUCT NAMENODES TO PREVIOUS AND NEXT NODES*/

struct numberNode {
    struct number number;          //name stuct call

    struct numberNode *pNext;    //pointer to next node
    struct numberNode *pPrev;    //pointer to previous node

};

到此:

struct numberNode {
    int number;                  //number
    struct numberNode *pNext;    //pointer to next node
    struct numberNode *pPrev;    //pointer to previous node

};

即。你不需要多于struct个。{/ p>

答案 1 :(得分:1)

保罗说你不一定需要这两个结构,但真正的问题是当你从文件中读取一个int时,你存储在变量“int number;”中每次调用函数insert_end(&amp; number);您发送变量号的地址,但在insert_end函数中,您将新节点中新号码的值分配给号码地址: var-&gt; number.number = num;。因此,在您的列表中,numberNode中的所有数字元素都将指向相同的地址。

快速修复是为文件中读取的每个整数分配新的内存空间。 例如:

int* number = (int*)malloc(sizeof(int));

while(fscanf(in_file,"%d", number)!=EOF)

{
    insert_end(number);
    number = (int*)malloc(sizeof(int));
}

你也可以按照Paul的建议删除结构中的指针:

struct numberNode {
    int number;                  //number
    struct numberNode *pNext;    //pointer to next node
    struct numberNode *pPrev;    //pointer to previous node
 };

希望它有所帮助,

[编辑]:为fhsilva提供更好的方法来管理尾部的+1,头部应始终参考列表的第一个元素,尾部应始终指向最后一个。这样你就不会通过列表插入到最后插入,因为你已经有了对最后一个元素的引用。(我无法评论fhsilva的答案,因为我刚刚订阅了SO并且没有足够的声誉...)

詹姆斯

答案 2 :(得分:0)

不确定为什么要遍历列表,因为它是双链接的。 这应该有效:

if (pHead==NULL){
    (...)
} else {
    pHead->pPrev = var;
    pTail->pNext = var;
    var->pPrev = pTail;
    var->pNext = pPrev;
    pTail = var;
}