Solved

returning to the head of linked list

Posted on 2000-03-08
18
546 Views
Last Modified: 2013-12-14
can anyone tell me the easiest way to go back to the head of the linked list at the end of the code below? i dun wish to add anything inside my struct unless i really have no choice.

inside my struct, i have a pointer
pointing to the nextPtr

thanks in advance!


ctr = 0;
if(*startPtr != NULL)
{
  while(*startPtr != NULL)
  {
    if(some condition)      
    {
      //delete one node from list
      //only enter here once
    }      
  (*startPtr) = (*startPtr)->nextPtr;
  ctr++;
  }
}
//go back to the head of the linked list before printing the linked list, else the list would be empty.

0
Comment
Question by:nglp
  • 7
  • 6
  • 2
  • +3
18 Comments
 
LVL 3

Expert Comment

by:arnond
ID: 2599393
All you need is an extra pointer (let's call it tempPtr) to the struct where you save startPtr in the begining (after ctr=0; do tempPtr=startPtr;) .
When you finish, all you need to do is: startPtr=tempPtr;.
This will not add fields to your struct, just use another pointer.

Hope this helps,
Arnon David.
0
 
LVL 2

Expert Comment

by:bbousquet
ID: 2599462
Just to add to arnond's comment/answer:

Usually when you manage linked lists you need to keep a pointer to the head of the list. How do you intend to free the dynamically allocated elements anyway?

arnond's comment suggests that - but I assume you must have a pointer to the head of the list stored somewhere in the source code.
0
 

Author Comment

by:nglp
ID: 2599471
what i did is

NODEPTR *tmpPtr = NULL;
tmpPtr = startPtr;
.........

startPtr = tmpPtr;


but then when i printed, the list is empty too.  the tmpPtr pointer also increments to the tail of the list just like the startPtr.  What went wrong??

i also tried
NODEPTR tmpPtr = *startPtr;
but the program has some error and stop running....


0
 
LVL 3

Expert Comment

by:arnond
ID: 2599499
what went wrong is:
strPtr is a NODEPTR but tmpPtr as declared is a pointer to NODEPTR and therefore, tmpPtr will point to startPtr.
You should declare tmpPtr as:
NODEPTR tmpPtr = startPtr;

Arnon David.
0
 

Author Comment

by:nglp
ID: 2599512
arnond:

i tried that before, but there's compiling error which says
'=': cannot convert from 'struct Node **' to 'struct Node *'
0
 
LVL 3

Expert Comment

by:arnond
ID: 2599519
how did you declare startPtr ?

can you post your entire code here ar anywhere we can download it from ?
either that or post your e-mail and I'll send you an e-mail so that you can send me the file.

Arnon
0
 
LVL 3

Expert Comment

by:arnond
ID: 2599527
how did you declare startPtr ?

can you post your entire code here ar anywhere we can download it from ?
either that or post your e-mail and I'll send you an e-mail so that you can send me the file.

Arnon
0
 

Author Comment

by:nglp
ID: 2599580
Adjusted points to 100
0
 

Author Comment

by:nglp
ID: 2599581
arnond: the entire code is very long, so i paste the relevant parts below.  why not u 'answer' the question, so that i can give u the points.


struct listNode
{
      int level1[3][5];
      int level[3][5];
      int var1;
      int var2;
      float var3;
      float var4;
      struct listNode *nextPtr;
};
typedef struct listNode LISTNODE;
typedef LISTNODE *LISTNODEPTR;

main()
{
      LISTNODEPTR startPtr = NULL;
      LISTNODEPTR closePtr = NULL;                        
      LISTNODEPTR tempPtr = NULL;
      LISTNODEPTR tmpPtr = NULL;
      insert_node(&startPtr);      
      tempPtr = startPtr;      
……..

tmpPtr = agenda(&tempPtr,&closePtr,method);
………..
}

LISTNODEPTR pop_agenda(LISTNODEPTR *startPtr,LISTNODEPTR *closePtr,int method)
{
      LISTNODEPTR *tmpPtr2 = NULL;
      LISTNODEPTR leastcostPtr = NULL;
      ……………….

      tmpPtr2 = startPtr;
      ctr = 0;
      if(*startPtr != NULL)
      {
            while(*startPtr != NULL)
            {
                  if(selectctr == ctr)      
                  {
                  add_node(closePtr,level,level1, *startPtr)->var1*startPtr)->var2,(*startPtr)->var3*startPtr)->var4);
                        add_node(&leastcostPtr,level,level1,(*startPtr)->var1*startPtr)->var2,(*startPtr)->var3*startPtr)->var4);
                        delete_node(startPtr,level1,(*startPtr)->var1,(*startPtr)->var3,(*startPtr)->var4);
                  }
                  (*startPtr) = (*startPtr)->nextPtr;
                  ctr++;
            }
      }
      startPtr = tmpPtr2;


      return (leastcostPtr);
}
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 3

Expert Comment

by:arnond
ID: 2599623
did my previous comments 'answer' you question or do you need more help ? If it was enough you can just click the 'accept comment as answer' button on the relevant comment. If not, please let me know and I'll look at the code more closely.

Arnon David.
0
 

Author Comment

by:nglp
ID: 2599637
u said to
NODEPTR tmpPtr = startPtr;

but i have the compiling error which i mentioned before. can u help me look at the code?  thanks a great deal :)
0
 
LVL 3

Expert Comment

by:arnond
ID: 2599869
the only thing I'm not sure about is :
typedef LISTNODE *LISTNODEPTR;

I'd try to not use the typedef and just ust LISTNODE* instead.
Prehaps it should be:
typedef LISTNODE* LISTNODEPTR;
note the difference of the position of the '*'.

Arnon.
0
 
LVL 1

Expert Comment

by:uniken
ID: 2600856
LISTNODEPTR pop_agenda(LISTNODEPTR *startPtr,LISTNODEPTR *closePtr,int method)
{
LISTNODEPTR tmpPtr2 = NULL;
LISTNODEPTR leastcostPtr = NULL;
……………….

tmpPtr2 = *startPtr;
ctr = 0;
if(*startPtr != NULL)
{
while(*startPtr != NULL)
{
if(selectctr == ctr)
{
add_node(closePtr,level,level1, *startPtr)->var1*startPtr)->var2,(*startPtr)->var3*startPtr)->var4);
add_node(&leastcostPtr,level,level1,(*startPtr)->var1*startPtr)->var2,(*startPtr)->var3*startPtr)->var4);
delete_node(startPtr,level1,(*startPtr)->var1,(*startPtr)->var3,(*startPtr)->var4);
}
(*startPtr) = (*startPtr)->nextPtr;
ctr++;
}
}
*startPtr = tmpPtr2;


return (leastcostPtr);
}


You are getting confused with pointer pointers :) Change the function to this version and I think it should work. I changed the following lines:

LISTNODEPTR tmpPtr2 = NULL;


tmpPtr2 = *startPtr;


*startPtr = tmpPtr2;

0
 
LVL 1

Expert Comment

by:uniken
ID: 2600890
A little more info:

In your version, the last line does nothing:

startPtr = tmpPtr2;

because arguments are passed by value. The value in the calling function is not altered. That's a reason for passing pointers as arguments.

In your code you modify the start pointer like this:

*startPtr = whatever

but when you set it back, you have:

startPtr = tmpPtr2;

You need to dereference the pointer here to set the start pointer back.

For next time, its usually a good idea to have a pointer to the head of the list as part of the list struct. If you store a pointer to the end as well, additions are much faster because you dont have to iterate through the list to find the end.

0
 
LVL 1

Expert Comment

by:tao_shaobin
ID: 2600934
Hi, nglp:

May I have a look at your function

insert_node(&startPtr);

According to your sample code, startPtr is a LISTNODEPTR.  Usually, we may use insert_node(startPtr) or insert_node(*startPtr).  But in your code, your insert the address of the pointer into the list.  Then, you should take care with your get_node(), delete_node, and othe functions.

tao_shaobin
0
 

Author Comment

by:nglp
ID: 2602877
okay, seems like it's very messy here... why not i restate my question?
i add an additional backPtr to my struct.  how do i amend the insert function below so that i can go the head of the list using

while(tmpPtr!=NULL)
{
tmpPtr=tmpPtr->backPtr;
}

p/s:thanks to all who commented.. but I really need to get this working with the least changes to the rest of my functions. thanks a million.


void insert(LISTNODEPTR *sPtr, char value)
{
      LISTNODEPTR newPtr, pregviousPtr,currentPtr;

      newPtr = malloc(sizeof(LISTNODE));

      if(newPtr != NULL)
      {
            newPtr->data = value;
            newPtr->nextPtr = NULL;

            previousPtr = NULL;
            currentPtr = *sPtr;

            while(currentPtr != NULL && value>currentPtr->data)
            {
                  previousPtr = currentPtr;
                  currentPtr = currentPtr->nextPtr;
            }

            if(previousPtr == NULL)
            {
                  newPtr->nextPtr = *sPtr;
                  *sPtr = newPtr;
            }
            else
            {
                  previousPtr->nextPtr = newPtr;
                  newPtr->nextPtr = currentPtr;
            }
      }
      else
            printf("%c not inserted.  No memory available. ",value);
}
0
 

Author Comment

by:nglp
ID: 2602880
I missed out on my last comment,take that my struct is of the form:
 
struct listNode
{
      char data;
      struct listNode *nextPtr;
};
typedef struct listNode LISTNODE;
typedef LISTNODE *LISTNODEPTR;
0
 

Accepted Solution

by:
nisa earned 100 total points
ID: 2609103
Hi,
   Are going to implement doubly linked list?? If so u need to have next and previous pointer as your struct member.

so you struct should be:

struct listNode
{
char data;
struct listNode *nextPtr;
struct listNode *backPtr;
};
(but doing so u have to add a code that make sure backPtr would always point to previous element of the list).
I think you can't got to the head if you do :
while(tmpPtr!=NULL)
{
tmpPtr=tmpPtr->backPtr;
}

Because "normally" end of linked list would point to NULL.

However the work around would be to add counter that count the current position to the head so that:

for(;count;count--)
  tmpPtr=tmpPtr->backPtr;

Otherwise would not find any NULL(or you will by accident) and your program will happilly crashed.


The easiest way to "go" to the head is that save the head before you traverse the list. However looking at your code .. there is no problem on locating head because:

newPtr->nextPtr = *sPtr;
*sPtr = newPtr;

so *sPtr is always pointing to Head.

Hope that helps.

Regards.




0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

In our object-oriented world the class is a minimal unit, a brick for constructing our applications. It is an abstraction and we know well how to use it. In well-designed software we are not usually interested in knowing how objects look in memory. …
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org (http://seleniumhq.org) Go to that link and select download selenium in the right hand columnThat will then direct you to their downlo…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now