FOXBAT
asked on
VERY EASY (traverse list) Question
Hi im interested in learning C language. I have a linked list and a traverse list function that works fine.
void listTraverse(List list, PtrToActionFunc actfptr)
{
ListNode *curr = list; /* ptr to current node */
for (curr = list; curr != NULL; curr = curr->nextptr)
actfptr(curr->dataptr); /* do action to node's data */
}
As you can see it traverses the whole list in the loop.
How can I modify the function so that it will perform a (DeQueue) operation?
As in, when run, the function should only display info from the 1st node. When run again, displaying data from 2nd node, then 3rd and so on.
void listTraverse(List list, PtrToActionFunc actfptr)
{
ListNode *curr = list; /* ptr to current node */
for (curr = list; curr != NULL; curr = curr->nextptr)
actfptr(curr->dataptr); /* do action to node's data */
}
As you can see it traverses the whole list in the loop.
How can I modify the function so that it will perform a (DeQueue) operation?
As in, when run, the function should only display info from the 1st node. When run again, displaying data from 2nd node, then 3rd and so on.
>when run, the function
1. do you mean multiple calls to the function in a single run of the program or mutiple runs ?
2. Also, do you wish to remove the data displayed from the list or do you wish to retain it
3. how is list node defined ?
in any case, since this is a learning exercise (whether your own or from school) I will give you some hints and you do it your self
biggest hint:
since you need to display only one element, you dont need the loop of traverse list ... but somehow you need to keep track of which element comes next ...
1. do you mean multiple calls to the function in a single run of the program or mutiple runs ?
2. Also, do you wish to remove the data displayed from the list or do you wish to retain it
3. how is list node defined ?
in any case, since this is a learning exercise (whether your own or from school) I will give you some hints and you do it your self
biggest hint:
since you need to display only one element, you dont need the loop of traverse list ... but somehow you need to keep track of which element comes next ...
ASKER
I meant multiple calls to the function, each call returning a single value from list.
It would be good if the function could remove the element and free up the allocated memory.
// my node is defined as
typedef struct listnode
{
void *dataptr; /* ptr to node's data */
struct listnode *nextptr; /* ptr to next list node */
} ListNode;
typedef ListNode *List; /* list is ptr to first list node */
I actually had the function working when i used a loop and a counter, to advance the current node to last location. I believe this method was too inefficient.
I would much rather keep a temp pointer to last node used.
Or extract data from 1st node, then remove it, and make the first pointer point to the new 1st node.
However I was unable to make these ideas work.
It would be good if the function could remove the element and free up the allocated memory.
// my node is defined as
typedef struct listnode
{
void *dataptr; /* ptr to node's data */
struct listnode *nextptr; /* ptr to next list node */
} ListNode;
typedef ListNode *List; /* list is ptr to first list node */
I actually had the function working when i used a loop and a counter, to advance the current node to last location. I believe this method was too inefficient.
I would much rather keep a temp pointer to last node used.
Or extract data from 1st node, then remove it, and make the first pointer point to the new 1st node.
However I was unable to make these ideas work.
this should be really simple
in your function to dequeue data
1. access the first node ( you will have starting address of the list )
2. make a copy of data
3. move that start pointer to second node
4. free the first node
5. return the copied data
to make changes to that starting address visible to rest of the program
1. pass pointer to the address (double indirection)
2. global variables ( not preferred )
in your function to dequeue data
1. access the first node ( you will have starting address of the list )
2. make a copy of data
3. move that start pointer to second node
4. free the first node
5. return the copied data
to make changes to that starting address visible to rest of the program
1. pass pointer to the address (double indirection)
2. global variables ( not preferred )
ASKER
i tried using this
void Deque(List list, PtrToActionFunc actfptr)
{
ListNode *curr = list;
actfptr(curr->dataptr); // remove data
curr = curr->nextptr;
list = curr;
free(curr);
}
but it made the program crash
void Deque(List list, PtrToActionFunc actfptr)
{
ListNode *curr = list;
actfptr(curr->dataptr); // remove data
curr = curr->nextptr;
list = curr;
free(curr);
}
but it made the program crash
ASKER
can you give example of how i could pass pointer to the address using double indirection
actfptr(curr->dataptr); // remove data
curr = curr->nextptr;
you remove the data and then you try to access it !!!
reverse their order
curr = curr->nextptr;
you remove the data and then you try to access it !!!
reverse their order
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
ListNode *curr = list;
actfptr(curr->dataptr); // copies data to functino, does not remove it
list = curr->nextptr; // makes list point to next node
free(curr); // im not sure how this works
actfptr(curr->dataptr); // copies data to functino, does not remove it
list = curr->nextptr; // makes list point to next node
free(curr); // im not sure how this works
ASKER
sorry just saw ur comment now
ASKER
Thanx 4 ur help Sunnycoder
i've been up since 6 in the morning and Its 12 am here. So i cant think at the moment.
im sure i'll get it 2 work in the morning = )
Thanx Cya
i've been up since 6 in the morning and Its 12 am here. So i cant think at the moment.
im sure i'll get it 2 work in the morning = )
Thanx Cya
good luck :)
ASKER
As i was playing C&C generals online it came 2 me = )
i wasnt returing the pointer!
im so silly LOL
Now this works fine = )
List Deque(List list, PtrToActionFunc actfptr)
{
ListNode *curr = list;
actfptr(curr->dataptr); // copies data to functino, does not remove it
list = curr->nextptr; // makes list point to next node
free(curr); // frees pointer
return list; // return pointer to list
}
i wasnt returing the pointer!
im so silly LOL
Now this works fine = )
List Deque(List list, PtrToActionFunc actfptr)
{
ListNode *curr = list;
actfptr(curr->dataptr); // copies data to functino, does not remove it
list = curr->nextptr; // makes list point to next node
free(curr); // frees pointer
return list; // return pointer to list
}
declare a variable pos in function ..
static int pos = 0 ;
int ctr = 0;
modify ur loop such that ctr doesnt exceed pos and print values till then
before exitting. increment the pos. pos will "remember" it next time u call the pos
u can even make pos as pointer to the next position in the list and start traversing frm there
u can eliminate the unnecessary counter
not_an_xpert :-(