简体   繁体   English

如何修改链表的 header 文件以处理多种类型的数据?

[英]How can i modify my header file of linked list to work with many type of data?

I made a header file for linked list like that.a header file for linked list It works properly with any data_t , but whenever I use it, I always have to modify struct data_t in the header file.它适用于任何data_t ,但每当我使用它时,我总是必须修改 header 文件中的struct data_t

How can I declare struct data_t in the main file?如何在主文件中声明struct data_t

Otherwhile, I have a linked list connecting to the other:另外,我有一个链接列表连接到另一个:

struct food_t{
        char fname[20];
        int time;
        food_t* f_next;
    };

struct person_t{
        char pname[20];
        food_t* food;
        person_t* p_next;
    };

How can I use functions in the.h file with both 2 linked lists?如何将 .h 文件中的函数与两个链表一起使用?

Here is my header file:这是我的 header 文件:

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

struct data_t{
    char name[20];
    char food[20];
};

struct node_t{
    data_t data;
    node_t *pNext;
};

struct list_t{
    node_t *pHead;
    node_t *pTail; 
};

//make new node with input data
node_t *newNode(data_t data){
    node_t *ptr= (node_t *) malloc(sizeof(node_t));
    
    if(ptr==NULL){
        printf("\nCan not allocate memory!!!");
        return NULL;
    }
    else{
        ptr->data=data;
        ptr->pNext=NULL;
        return ptr;
    }
}

//initial list
void initList(list_t& ls){ 
    ls.pHead = ls.pTail = NULL;
}

//free list
void lsFree(list_t &ls){
    node_t *tmp;
    while((tmp=ls.pHead)!=NULL){        
        ls.pHead=ls.pHead->pNext;
        free(tmp);
    }
}

//check empty
bool isEmpty(list_t ls){
    if(ls.pHead==NULL)
        return true;
    else return false;
}

//get size
int getSize(list_t ls){
    if(isEmpty(ls)){
        return 0;
    }
    else{
        int size=0;
        node_t *ptr;
        ptr=ls.pHead;
        while(ptr!=NULL){
            size++;
            ptr=ptr->pNext;
        }
        return size;
    }
}

//Search node with input data
node_t *search(list_t ls, data_t data);

//get id of node. For root(head): root_id=0
int get_node_index(list_t ls, node_t *node){
    if(isEmpty(ls)){
        printf("List is empty!!!\n");
        return -1;
    }
    else
    {
        int index=0;
        node_t *ptr=ls.pHead;
        for(ptr; ptr!=node; ptr=ptr->pNext){ 
            index++;
        }
        return index;
    }
}

//find pointer of node
node_t *findNode(list_t ls, int id){
    node_t *ptr=ls.pHead;
    while(get_node_index(ls, ptr)!=id){
        ptr=ptr->pNext;
    }
    return ptr;
}

//add node to head
void addHead(list_t& ls, node_t *node){
    if(isEmpty(ls)){
        ls.pHead= ls.pTail= node;
    }
    else {
        node->pNext = ls.pHead; 
        ls.pHead= node;
    }
}

//del node from head
void delHead(list_t &ls){
    if(isEmpty(ls)){
        printf("List is empty!!!\n");
    }
    else
    {
        node_t *ptr;
        ptr=findNode(ls, 0); 
        ls.pHead= ls.pHead->pNext;
        free(ptr); 
    }
}

//add node to tail
void addTail(list_t &ls, node_t *node){
    if(isEmpty(ls)){
        ls.pHead=ls.pTail=node;
    }
    else{
        ls.pTail->pNext=node;
        ls.pTail=node;
    }
}

//del node from tail
void delTail(list_t &ls){
    if(isEmpty(ls)){
        printf("List is empty!!!");
    }
    else{
        int n= getSize(ls);
        node_t *ptr=findNode(ls, n-2);
        ls.pTail= ptr;
        free(ptr->pNext);
        ptr->pNext=NULL;
    }
}

//add node at id: new node will have this id
void insert_at_id(list_t &ls, int id, node_t *node){
    if(isEmpty(ls)){
        ls.pHead= ls.pTail= node;
    }
    else
    {
        node_t *ptr=findNode(ls, id-1);
        node->pNext= ptr->pNext;
        ptr->pNext=node;
    }   
}

//Del node at id 
void del_at_id(list_t &ls, int id){
    if(isEmpty(ls)){
        printf("List is empty!!!\n");
    }
    else if(id==0) delHead(ls);
    else
    {
        node_t *ptr=findNode(ls, id-1);
        node_t *tmp=ptr->pNext;
        ptr->pNext=tmp->pNext;
        if(tmp==ls.pTail) ptr=ls.pTail;
        free(tmp); 
    }
}

//Reverse list
void reverse_list(list_t &ls){
    int size=getSize(ls);
    node_t *tail= findNode(ls, size-1);
    node_t *head= findNode(ls, 0);
    for(int i=size-1; i>=0; i--){
        if(i>0){
            node_t *ptr=findNode(ls, i);
            node_t *ptr_before=findNode(ls, i-1);
            ptr->pNext=ptr_before;
        }
        else{
            node_t *ptr=findNode(ls, 0);
            ptr->pNext=NULL;
        }        
    }
    ls.pHead=tail;
    ls.pTail=head;
}

//Export to file
void lsOut(list_t ls, FILE *fout){
    if(isEmpty(ls)){
        printf("List is emptry!!!\n");
    }
    else{
        node_t *ptr=ls.pHead;
        while(ptr!= NULL){
            fwrite(ptr, sizeof(data_t),1, fout);
            ptr=ptr->pNext;
        }
    }
}


//Search and move to head
void move_to_head(list_t &ls, node_t *ptr){
    node_t *tmp=newNode(ptr->data);
    addHead(ls, tmp);
    del_at_id(ls, get_node_index(ls, ptr));
}

//Swap data 2 nodes
void swap(node_t *n1, node_t *n2){
    data_t tmp= n1->data;
    n1->data=n2->data;
    n2->data=tmp;
}

You can just use void* instead of data_t and use cast to deal with that.您可以只使用 void* 而不是 data_t 并使用 cast 来处理它。 So since your data is a pointer, you can point to whatever you want.所以由于你的数据是一个指针,你可以指向任何你想要的。 Take a look at this node_t structure:看一下这个 node_t 结构:

struct node_t {
    void *data;
    node_t *pNext;
};

Let's ignore all the linked list logic for now and focus only on void *data .让我们暂时忽略所有链表逻辑,只关注void *data So:所以:

  • We can store an integer (777) pointer in data:我们可以在数据中存储一个 integer (777) 指针:
node_t n;
int *predata = (int*)malloc(sizeof(int));
*predata = 777;
n.data = predata;
printf("%d\n", *((int*)( n.data )));
  • Or we can store and retrieve a string:或者我们可以存储和检索一个字符串:
node_t n;
char *s = (char*)malloc(4);
sprintf(s, "abc");
n.data = s;
printf("%s\n", (char*)n.data); 

So based on this, you can actually use whatever you want as data but you need to make sure to do the proper casts.因此,基于此,您实际上可以使用任何您想要的数据作为数据,但您需要确保进行正确的转换。 Note for implementing this way, you will need to do dynamic allocations for all data content you're using.请注意,要以这种方式实现,您需要对正在使用的所有数据内容进行动态分配。 So you're not using a 'list with any type'.因此,您没有使用“任何类型的列表”。 You're working with a list of pointers.您正在使用指针列表。

Note : I think you're using C++.注意:我认为您使用的是 C++。 So you can take a look at C++ templates to solve your problem in a C++ way.因此,您可以查看 C++ 模板,以 C++ 方式解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我在链表的末尾创建一个垃圾节点,只是为了指定NULL。 如何修改代码以防止这种情况? - I am creating a garbage node at the end of linked list just to specify NULL. How can I modify my code to prevent that? 我可以修改共享库文件以使其与可执行文件一起正常工作吗 - Can I modify a shared library file to work fine with my executable 如何在C中使用带有头文件的链表? - How to use a linked list with a header file in C? 将文件传递到链表时,如何读取文件并确定其数据表示形式? - How can I read a file and determine its data representation as I pass it into a linked list? 我无法使用链表中的链表 - I can not work with linked list inside linked list 如何创建 (C) 函数以使用“读取”将文件中的数据读取到链表中? - How can I create a (C) function to read data from a file into a linked-list using 'read'? 如何显示在链接列表中创建的数据? - How can I display the data I created in a linked list? 如何在链表中打印值? - How can I print the values in my linked list? 如何在我的链表实现中修复此内存泄漏? - How can I fix this memoryleak in my implementaion of linked list? 如何删除双向链表的前端节点? - How can I delete the front node of my doubly linked list?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM