[英]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:所以:
node_t n;
int *predata = (int*)malloc(sizeof(int));
*predata = 777;
n.data = predata;
printf("%d\n", *((int*)( n.data )));
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.