C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old September 18th, 2012, 01:18 AM
JamesA1 JamesA1 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Sep 2012
Posts: 12 JamesA1 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 18 m 41 sec
Reputation Power: 0
How to acces two subsequent nodes in a linked list?

Hi,

Just like we can access two elements in a for loop or in an array as i and i+1, assuming we have the for loop like:

for (int i = __ ; ___ ; i++)

, is there a similar way in which I can access the subsequent nodes of a linked list?

What I would like to do is to find the difference between the data field of one node and the next one but I do not know how to do that. The outline of my function is like:

node* ProcessCluster(struct node *q) {

struct node *temp;
temp = q;

while(temp->link!=NULL) {

// Access two subsequent elements here. Can I modify
// temp = temp->next in some way to access the current and
// the next element too?

}


}

Reply With Quote
  #2  
Old September 18th, 2012, 01:42 AM
nebelung's Avatar
nebelung nebelung is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2008
Posts: 222 nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level) 
Time spent in forums: 6 Days 20 h 45 m 40 sec
Reputation Power: 234
If I understood you correctly it's just a matter of double indirection
temp->link basically is a pointer to the next node wich can be dereferenced to access it's data (temp->link->data), or you can add another indirection to access the one element after the next ( i + 2 )
temp->link->link which also can be dereferenced, etc. I think you get the idea



c Code:
Original - c Code
  1. while ( temp->link != NULL )  {
  2.    /* assuming data is of basic type */
  3.    int diff = temp->data - temp->link->data;
  4.    .....
  5. }

Reply With Quote
  #3  
Old September 18th, 2012, 01:49 AM
JamesA1 JamesA1 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Sep 2012
Posts: 12 JamesA1 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 18 m 41 sec
Reputation Power: 0
Thanks for the prompt answer! Much appreciated.

Reply With Quote
  #4  
Old September 18th, 2012, 04:57 AM
JamesA1 JamesA1 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Sep 2012
Posts: 12 JamesA1 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 18 m 41 sec
Reputation Power: 0
Hi Nebelung,

I have another question that I would like to ask, given your knowledge of linked lists.

I have a linked list of structs that stores (x,y) coordinates of start points and end points like:

Code:
struct cluster
{		
		float startcoord_x; 
		float startcoord_y;
		float endcoord_x;
		float endcoord_y;
};

struct node
{
        cluster CLUST;
	struct node* link;
}; 


So I am now trying to see if the distance between one point and the next is small, and if it is, then I "merge" the two nodes by rewriting the end point of the current point with the end point of the next

That is, if my list is like

Start_x Start_y End x_ End_y
10 10 20 20
22 22 30 30

and after processing, it should be like

Start_x Start_y End x_ End_y
10 10 30 30


I have done a program that can do the linked list creation, deletion and everything else, but I am now at the part where I need to find the distance from one point to the next (done) and then update/rewrite the node..and this is the part where I am stuck here. My code so far is


Code:
node* ProcessCluster(struct node **q) {

        struct node *temp;
        struct node *dummy;
	temp = *q;  
        float diff = 0.0 ;
         
        while(temp->link!=NULL) {

            // Calculate distance from *end* of *current* cluster to *start* of *last* cluster
            diff = sqrt(pow((temp->CLUST.endcoord_x - temp->link->CLUST.startcoord_x),2)+ pow((temp->CLUST.endcoord_y - temp->link->CLUST.startcoord_y),2));

            // If distance is less than 150mm, join the two clusters
            if (diff <= 100.0){           
                printf("Distance to next cluster is %f \n", diff);

                // 1. Change the *end coordinate of  CURRENT cluster* to  *end coordinate of next cluster*        
                temp->CLUST.endcoord_x = temp->link->CLUST.endcoord_x;
                temp->CLUST.endcoord_y = temp->link->CLUST.endcoord_y;
               
                // 2. "Delete" the next node
                delete temp;
                dummy = temp->link->link;
                free(temp);
                temp = dummy;
                
            }  

            temp=temp->link;         

        }  
        return temp;

}


I am completely stumped at the part labelled 2. And I have a number of problems. First, even if I comment out the entire contents of the inside of the while loop and print my list, it only shows the first node. So the way in which I am looping is changing my list. Then, I am not sure of the part where I "delete" my next node by changing the pointer of current node to point to the node after the next.

Could you give me any hints?

Reply With Quote
  #5  
Old September 18th, 2012, 06:42 AM
salem's Avatar
salem salem is offline
Contributed User
Click here for more information
 
Join Date: Jun 2005
Posts: 3,838 salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)salem User rank is General 12nd Grade (Above 100000 Reputation Level)  Folding Points: 153 Folding Title: Novice Folder
Time spent in forums: 2 Months 3 Weeks 2 Days 17 h 9 m 51 sec
Reputation Power: 1774
> dummy = temp->link->link;
You need to be careful here, because if you're deleting say the last node of your linked list, then you're in trouble here.

> while(temp->link!=NULL)
Likewise, if the list is empty to begin with.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper

Reply With Quote
  #6  
Old September 18th, 2012, 07:21 AM
bdb bdb is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2012
Posts: 156 bdb User rank is Sergeant Major (2000 - 5000 Reputation Level)bdb User rank is Sergeant Major (2000 - 5000 Reputation Level)bdb User rank is Sergeant Major (2000 - 5000 Reputation Level)bdb User rank is Sergeant Major (2000 - 5000 Reputation Level)bdb User rank is Sergeant Major (2000 - 5000 Reputation Level)bdb User rank is Sergeant Major (2000 - 5000 Reputation Level) 
Time spent in forums: 1 Week 15 h 48 m 11 sec
Reputation Power: 32
Quote:
Originally Posted by JamesA1
for (int i = __ ; ___ ; i++)


Code:
for (struct whatever *curr = ___; curr; curr = curr->next)

But I prefer the while option.

Reply With Quote
  #7  
Old September 18th, 2012, 07:47 AM
nebelung's Avatar
nebelung nebelung is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2008
Posts: 222 nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level)nebelung User rank is Captain (20000 - 30000 Reputation Level) 
Time spent in forums: 6 Days 20 h 45 m 40 sec
Reputation Power: 234
I'll incorporate the astute remarks made by salem.

1. I advice you not to use float but instead use double (this was discussed a number of times in this forum and other places).
2. Although it is not directly related to you question I think that it is beneficial to define a coordinate structure it greatly enhances the readability and maintainabillity of your code.
3. It is better to avoid magic numbers define some constant to represent the minimal distance.
4.
c Code:
Original - c Code
  1. dummy = temp->link->link;
  2.                 free(temp);
  3.                 temp = dummy;
  4.                 .....
  5.                 temp=temp->link; 


notice that after the removal of the next node you move to the one after the next (temp = dummy) and after you get out of the "if" block you again advance the temp pointer which results in double advance, I doubt that this is really what you want, so insted you should restore the link after the deletion like so:
c Code:
Original - c Code
  1. temp->link = dummy;


4. Also notice what would happen if we are two elements before the end of the list and we delete the next node and think why we should add an additional condition in the while loop.

All the aforementioned ideas are incorporated into the following code (notice that I haven't compiled it so there might be errors)

c Code:
Original - c Code
  1. typedef struct coord
  2. {
  3.     double x;
  4.     double y;
  5. } Coord;
  6.  
  7. typedef struct cluster
  8. {      
  9.     Coord startCoord;
  10.     Coord endCoord;
  11. } Cluster;
  12.  
  13. typedef struct node
  14. {
  15.     Cluster cluster;
  16.     struct node* link;
  17. } Node;
  18.  
  19. double computeEuclidDist (const Coord a, const Coord b)
  20. {
  21.     return sqrt ( pow(a.x - b.x, 2) + pow(a.y - b.y, 2) );
  22. }
  23.  
  24. /* constants */
  25. const double MIN_DIST = 150;
  26.  
  27. ....
  28.  
  29.  
  30. Node* ProcessCluster(Node **q)
  31. {
  32.    
  33.     if (*q == NULL || (*q)->link == NULL) {
  34.         fprintf(stderr, "The list must contain at least two clusters\n");
  35.         return *q;
  36.     }
  37.    
  38.     Node *temp = *q;
  39.     Node *dummy;
  40.     double dist;
  41.    
  42.     while(temp != NULL && temp->link != NULL) {
  43.  
  44.         // Calculate distance from *end* of *current* cluster to *start* of *last* cluster
  45.         dist = computeEuclidDist (temp->cluster.endCoord, temp->link->cluster.startCoord);
  46.  
  47.         // If distance is less than 150mm, join the two clusters
  48.         if (dist <= MIN_DIST){           
  49.             fprintf(stdout, "Distance to next cluster is %f \n", dist);
  50.  
  51.             // 1. Change the *end coordinate of  CURRENT cluster* to  *end coordinate of next cluster*       
  52.             temp->cluster.endCoord = temp->link->cluster.endCoord;
  53.           
  54.             // 2. "Delete" the next node
  55.             dummy = temp->link->link;
  56.             free (temp->link);
  57.             temp->link = dummy;
  58.         } 
  59.         temp=temp->link;         
  60.     } 
  61.     return temp;
  62. }

Last edited by nebelung : September 18th, 2012 at 09:37 AM.

Reply With Quote
  #8  
Old September 19th, 2012, 02:24 AM
JamesA1 JamesA1 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Sep 2012
Posts: 12 JamesA1 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 h 18 m 41 sec
Reputation Power: 0
Thanks so much for your reply nebelung.

I have learnt more from forums like these than from my classes!
I am currently implementing the function!

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > How to acces two subsequent nodes in a linked list?

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap