MHB Why Use a Helper Variable When Inserting an Element in an Array?

  • Thread starter Thread starter mathmari
  • Start date Start date
  • Tags Tags
    Array
AI Thread Summary
The discussion centers on the insertion of a new star system into an array of star systems with the goal of achieving O(1) time complexity. Participants clarify that inserting an element at a specific index in an array is O(1), but managing the size of the array requires tracking the number of existing systems. A proposed solution involves using a separate variable to keep track of the number of star systems, allowing for efficient insertion. There is also debate about whether to treat the array as a linked list or maintain it as a fixed-size array. The final consensus suggests initializing only the new star system rather than all systems during insertion.
  • #51
I like Serena said:
Huh? :confused:Currently you are executing [m]StarS[k].plasy=plansystem;[/m].
If [m]StarS[k].plasy[/m] already contained planets, those will become inaccessible after the assignment. (Wasntme)

So is the for loop as followed?? (Wondering)

Code:
for(i=0; i<nrStarS; i++){
	if(StarS[i].ss==ss){
	      k=i;
	      while(StarS[k].plasy != NULL){
		      StarS[k].plasy=StarS[k].plasy->next;
	      }
	      StarS[k].plasy=plansystem;
         }
}
 
Technology news on Phys.org
  • #52
mathmari said:
So is the for loop as followed?? (Wondering)

Code:
for(i=0; i<nrStarS; i++){
	if(StarS[i].ss==ss){
	      k=i;
	      while(StarS[k].plasy != NULL){
		      StarS[k].plasy=StarS[k].plasy->next;
	      }
	      StarS[k].plasy=plansystem;
         }
}

Let's see... suppose we initially have 2 planets. Something like:

$$plasy \to \boxed{solid_1} \to \boxed{solid_2}\to NULL$$
After the first execution of [m]StarS[k].plasy=StarS[k].plasy->next;[/m], we have:
\begin{array}{}
&plasy&&plansystem\\
&\downarrow &&\downarrow\\
\boxed{solid_1} \to &{\boxed{solid_2}}\to & NULL \quad & {\boxed{solid_{new}}}\to NULL
\end{array}

But... but... now ${solid}_1$ is not accessible any more.
That can't be right! (Worried)

We will finally have:
\begin{array}{}
&&&plasy\\
&&&\downarrow \\
\boxed{solid_1} \to &{\boxed{solid_2}}\to & NULL \quad & {\boxed{solid_{new}}}\to NULL
\end{array}

This is the same as previously!
The original list is not accessible anymore. (Worried)
 
  • #53
I like Serena said:
Let's see... suppose we initially have 2 planets. Something like:

$$plasy \to \boxed{solid_1} \to \boxed{solid_2}\to NULL$$
After the first execution of [m]StarS[k].plasy=StarS[k].plasy->next;[/m], we have:
\begin{array}{}
&plasy&&plansystem\\
&\downarrow &&\downarrow\\
\boxed{solid_1} \to &{\boxed{solid_2}}\to & NULL \quad & {\boxed{solid_{new}}}\to NULL
\end{array}

But... but... now ${solid}_1$ is not accessible any more.
That can't be right! (Worried)

We will finally have:
\begin{array}{}
&&&plasy\\
&&&\downarrow \\
\boxed{solid_1} \to &{\boxed{solid_2}}\to & NULL \quad & {\boxed{solid_{new}}}\to NULL
\end{array}

This is the same as previously!
The original list is not accessible anymore. (Worried)

We assign the value [m]plansystem[/m] to [m]StarS[k].plasy[/m] when [m]StarS[k].plasy==NULL[/m] or not?? (Wondering)
 
  • #54
mathmari said:
We assign the value [m]plansystem[/m] to [m]StarS[k].plasy[/m] when [m]StarS[k].plasy==NULL[/m] or not?? (Wondering)

If [m]StarS[k].plasy==NULL[/m], that is fine.
Otherwise we need to do something to properly insert [m]plansystem[/m] into the list. (Thinking)
 
  • #55
I like Serena said:
If [m]StarS[k].plasy==NULL[/m], that is fine.
Otherwise we need to do something to properly insert [m]plansystem[/m] into the list. (Thinking)

But doesn't the pointer plasy show always to NULL, after the while loop?? (Wondering)
 
  • #56
mathmari said:
But doesn't the pointer plasy show always to NULL, after the while loop?? (Wondering)

Yes it does.
However, plasy is always supposed to point the the first element in the list.
So you shouldn't change it to point to the last element. (Shake)Instead I suggest to either add the new plansystem to the beginning of the list, like this:
Code:
// Insert plansystem at the beginning of the list
plansystem->next = StarS[k].plasy;
StarS[k].plasy = plansystem;

Or add the new plansystem to the end of the list, like this:
Code:
if (StarS[k].plasy == NULL) {
    // List is empty: replace with new plansystem
    StarS[k].plasy = plansystem;
} else {
    // Find last node
    plansys_t *last = StarS[k].plasy;
    while (last->next != NULL) {
        last = last->next;
    }
    // Append new plansystem to the last node
    last->next = plansystem;
}
(Thinking)
 
  • #57
I like Serena said:
Yes it does.
However, plasy is always supposed to point the the first element in the list.
So you shouldn't change it to point to the last element. (Shake)Instead I suggest to either add the new plansystem to the beginning of the list, like this:
Code:
// Insert plansystem at the beginning of the list
plansystem->next = StarS[k].plasy;
StarS[k].plasy = plansystem;

Or add the new plansystem to the end of the list, like this:
Code:
if (StarS[k].plasy == NULL) {
    // List is empty: replace with new plansystem
    StarS[k].plasy = plansystem;
} else {
    // Find last node
    plansys_t *last = StarS[k].plasy;
    while (last->next != NULL) {
        last = last->next;
    }
    // Append new plansystem to the last node
    last->next = plansystem;
}
(Thinking)

I see... (Sun)

So that we print the identifiers "solid" which belong to a given star system "ss", do we return from the function Beginning the value of k ??

Then at the main do we write the following?? (Wondering)

Code:
printf("Give the identifier solid and ss: \n");
scanf("%d %d", &solid, &ss);
Beginning(solid, ss);
plansys_t *p = StarS[k].plasy;
while(p != NULL){
	printf(" %d ", p->solid);
	p=p->next;
}
 
  • #58
mathmari said:
I see... (Sun)

So that we print the identifiers "solid" which belong to a given star system "ss", do we return from the function Beginning the value of k ??

Then at the main do we write the following?? (Wondering)

Code:
printf("Give the identifier solid and ss: \n");
scanf("%d %d", &solid, &ss);
Beginning(solid, ss);
plansys_t *p = StarS[k].plasy;
while(p != NULL){
	printf(" %d ", p->solid);
	p=p->next;
}

That looks okay, although you should account for the possibility that the star system cannot be found.
Btw, didn't you forget to give $k$ a value? (Worried)
 
  • #59
I like Serena said:
That looks okay, although you should account for the possibility that the star system cannot be found.
Btw, didn't you forget to give $k$ a value? (Worried)

Code:
int k = -1;

int Beginning(int solid, int ss){
		int i;

        // Add a planetary system to the list of the planetary system of the star system
        plansys_t *plansystem = calloc(1, sizeof(plansys_t));
        
        plansystem->solid=solid;
        plansystem->asteroids=NULL;
        plansystem->next=NULL;
		for(i=0; i<nrStarS; i++){
			if(StarS[i].ss==ss){
				k=i;
				if (StarS[k].plasy == NULL) {
                     // List is empty: replace with new plansystem
                     StarS[k].plasy = plansystem;
                } else {
                    // Find last node
                    plansys_t *last = StarS[k].plasy;
                    while (last->next != NULL) {
                          last = last->next;
                    }
                    // Append new plansystem to the last node
                    last->next = plansystem;
               }
			}
		}
		if(k==-1){
			printf("The star system with identifier %d couldn't be found\n", ss);
		}
		return k;
}

int main(){
    int solid, ss;
    printf("Give the identifier solid and ss: \n");
    scanf("%d %d", &solid, &ss);
    Beginning(solid, ss);
    plansys_t *p = StarS[k].plasy;
    while(p != NULL){
	   printf(" %d ", p->solid);
	   p=p->next;
    }
    return 0;
}

At the function Beginning do we not account for the possibility that the star system cannot be found?? (Wondering)

By returning $k$ from the function Beginning doesn't it have the value at the main when calling the function?? (Wondering)
 
  • #60
mathmari said:
Code:
int k = -1;

int Beginning(int solid, int ss){
		int i;

        // Add a planetary system to the list of the planetary system of the star system
        plansys_t *plansystem = calloc(1, sizeof(plansys_t));
        
        plansystem->solid=solid;
        plansystem->asteroids=NULL;
        plansystem->next=NULL;
		for(i=0; i<nrStarS; i++){
			if(StarS[i].ss==ss){
				k=i;
				if (StarS[k].plasy == NULL) {
                     // List is empty: replace with new plansystem
                     StarS[k].plasy = plansystem;
                } else {
                    // Find last node
                    plansys_t *last = StarS[k].plasy;
                    while (last->next != NULL) {
                          last = last->next;
                    }
                    // Append new plansystem to the last node
                    last->next = plansystem;
               }
			}
		}
		if(k==-1){
			printf("The star system with identifier %d couldn't be found\n", ss);
		}
		return k;
}

int main(){
    int solid, ss;
    printf("Give the identifier solid and ss: \n");
    scanf("%d %d", &solid, &ss);
    Beginning(solid, ss);
    plansys_t *p = StarS[k].plasy;
    while(p != NULL){
	   printf(" %d ", p->solid);
	   p=p->next;
    }
    return 0;
}

At the function Beginning do we not account for the possibility that the star system cannot be found?? (Wondering)

By returning $k$ from the function Beginning doesn't it have the value at the main when calling the function?? (Wondering)

We account for it inside the function yes.
But when it fails, we have $k=-1$.
Then, in the main() function the StarS[] array still gets indexed with $k=-1$, which will result in a bit of madness and chaos. (Worried)Btw, it is bad programming style to keep the $k$ outside the function in the global namespace. It is better to declare it inside the function, and when you call the function keep track of the value that the function returned. (Nerd)
 
  • #61
I like Serena said:
We account for it inside the function yes.
But when it fails, we have $k=-1$.
Then, in the main() function the StarS[] array still gets indexed with $k=-1$, which will result in a bit of madness and chaos. (Worried)

So, we could write the following if in the main() function, after calling the function, instead of writing it in the function Beginning, right?? (Wondering)

Code:
if(k==-1){
	printf("The star system with identifier %d couldn't be found\n", ss);
}
I like Serena said:
Btw, it is bad programming style to keep the $k$ outside the function in the global namespace. It is better to declare it inside the function, and when you call the function keep track of the value that the function returned. (Nerd)

Ok, I changed it! (Yes)

Now it works! (Happy)
 
  • #62
mathmari said:
Code:
int nrStarS = 0;

int Constitution(int ss) {
        int i;

        // Add a star system to the the array of stars
        starsy_t *starsystem = &StarS[nrStarS];
        nrStarS++;

        // Initialize the new star system
        starsystem->ss = ss;
        starsystem->plasy=starsystem->Sentinel;
	for(i=0; i<max; i++){
		starsystem->ffplan[i].fp=INT_MAX;
		starsystem->ffplan[i].ff=NULL;
	}

        // Return the index of the star system that was added
	return (nrStarS - 1);
}
	
	
int main(){
	int i, ss;
	printf("Give the identifier ss: \n");
	scanf("%d", &ss);
	Constitution(ss);
	for(i=0; i<nrStarS; i++){
		printf(" %d ", StarS[i].ss);
	}
        return 0;
}

Should I declare the variable [m]nrStarS [/m] also inside the function Constitution?? (Wondering)
 
  • #63
mathmari said:
So, we could write the following if in the main() function, after calling the function, instead of writing it in the function Beginning, right?? (Wondering)

Code:
if(k==-1){
	printf("The star system with identifier %d couldn't be found\n", ss);
}

Yes. (Nod)
Ok, I changed it! (Yes)

Now it works! (Happy)

Good! (Smile)
mathmari said:
Should I declare the variable [m]nrStarS [/m] also inside the function Constitution?? (Wondering)

No.
[m]nrStarS[/m] tracks a global state, together with the StarS[] array.
It is appropriate that it is global. (Nerd)
 
  • #64
I like Serena said:
No.
[m]nrStarS[/m] tracks a global state, together with the StarS[] array.
It is appropriate that it is global. (Nerd)

Ahaaa... I see... (Star)Then I have to write also an other function for the constitution of an asteroid with identifier "as" at the planetary system "solid".
"gap" is the gap between the new asteroid and the object.
The new asteroid should be added in the appropriate position, in respect of the "gap", in the list of asteroids.
The field gap, that corresponds to the new asteroid, contains the gap from the previous asteroid in the list of asteroids and not the gap from the object.

I have done the following:

Code:
int asteroid_constitution(int as, int gap, int solid){
	int i, g=0;
	asteroid_t *ast = calloc(1, sizeof(asteroid_t));
	ast->as=as;
	ast->gap=gap;
	ast->prev=NULL;
	ast->next=NULL;
	plansys_t *p=StarS[0].plasy;;
	for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while(p->solid != solid){
			p=p->next;
		}
	}
	if (p->asteroids==NULL){
		p->asteroids=ast;
	}
	else{
		asteroid_t *last=p->asteroids;
		asteroid_t *q=p->asteroids;
		g=g+ast->gap;
		while(g<ast->gap){
			last=last->next;
		}
		ast->next=last->next;
		ast->prev=last;
		last->next=ast;
		ast->gap=ast->gap-g;
		q=ast->next;
		q->gap=q->gap-ast->gap;		
	}
	return 0;
}

Is this correct?? (Wondering)
 
  • #65
mathmari said:
Ahaaa... I see... (Star)Then I have to write also an other function for the constitution of an asteroid with identifier "as" at the planetary system "solid".
"gap" is the gap between the new asteroid and the object.
The new asteroid should be added in the appropriate position, in respect of the "gap", in the list of asteroids.
The field gap, that corresponds to the new asteroid, contains the gap from the previous asteroid in the list of asteroids and not the gap from the object.

I have done the following:

Code:
int asteroid_constitution(int as, int gap, int solid){
	int i, g=0;
	asteroid_t *ast = calloc(1, sizeof(asteroid_t));
	ast->as=as;
	ast->gap=gap;
	ast->prev=NULL;
	ast->next=NULL;
	plansys_t *p=StarS[0].plasy;;
	for(i=0; i<Sfreep; i++){
		p=StarS[i].plasy;
		while(p->solid != solid){
			p=p->next;
		}
	}
	if (p->asteroids==NULL){
		p->asteroids=ast;
	}
	else{
		asteroid_t *last=p->asteroids;
		asteroid_t *q=p->asteroids;
		g=g+ast->gap;
		while(g<ast->gap){
			last=last->next;
		}
		ast->next=last->next;
		ast->prev=last;
		last->next=ast;
		ast->gap=ast->gap-g;
		q=ast->next;
		q->gap=q->gap-ast->gap;		
	}
	return 0;
}

Is this correct?? (Wondering)

What is [m]Sfreep[/m]? (Wondering)

What if [m]q[/m] is NULL? (Wondering)

Shouldn't the asteroid after the new one have its [m]prev[/m] updated? (Wondering)
 
  • #66
I like Serena said:
What is [m]Sfreep[/m]? (Wondering)

[m]Sfreep[/m] should be replaced with [m]nrStarS[/m] (Blush)
I like Serena said:
What if [m]q[/m] is NULL? (Wondering)

We have initialized [m]q[/m] as followed

[m]asteroid_t *q=p->asteroids;[/m]

right?? (Wondering)

In the else statement [m]p[/m] is not NULL. So, can [m]q[/m] be NULL ?? (Wondering)
I like Serena said:
Shouldn't the asteroid after the new one have its [m]prev[/m] updated? (Wondering)

Could I maybe do it as followed?? (Wondering)

Code:
ast->next=last->next;
last->next->prev=ast;
ast->prev=last;
last->next=ast;
ast->gap=ast->gap-g;
q=ast->next;
q->gap=q->gap-ast->gap;
 
  • #67
mathmari said:
[m]Sfreep[/m] should be replaced with [m]nrStarS[/m] (Blush)

We have initialized [m]q[/m] as followed

[m]asteroid_t *q=p->asteroids;[/m]

right?? (Wondering)

That is at first, but you never use it like that.
So you might as well not initialize it, or initialize it to NULL. (Nerd)
In the else statement [m]p[/m] is not NULL. So, can [m]q[/m] be NULL ?? (Wondering)

When you do give [m]q[/m] a value in [m]q=ast->next[/m], it can be NULL. (Shake)
Could I maybe do it as followed?? (Wondering)

Code:
ast->next=last->next;
last->next->prev=ast;

In principle, yes, but what if [m]last->next[/m] is NULL? (Wondering)

Code:
q=ast->next;
q->gap=q->gap-ast->gap;

What if [m]q[/m] becomes NULL here?
Then you are following a NULL pointer to madness and chaos! (Evilgrin)
 
  • #68
I like Serena said:
That is at first, but you never use it like that.
So you might as well not initialize it, or initialize it to NULL. (Nerd)When you do give [m]q[/m] a value in [m]q=ast->next[/m], it can be NULL. (Shake)

In principle, yes, but what if [m]last->next[/m] is NULL? (Wondering)
What if [m]q[/m] becomes NULL here?
Then you are following a NULL pointer to madness and chaos! (Evilgrin)

So, should we add the condition [m]last->next!=NULL[/m] in the while?? (Wondering)

Code:
asteroid_t *last=p->asteroids;
asteroid_t *q=NULL;
g=g+ast->gap;
while(g<ast->gap && last->next!=NULL){
	last=last->next;
}
ast->next=last->next;
ast->prev=last;
last->next=ast;
ast->gap=ast->gap-g;
q=ast->next;
q->gap=q->gap-ast->gap;
 
  • #69
mathmari said:
So, should we add the condition [m]last->next!=NULL[/m] in the while?? (Wondering)

Code:
asteroid_t *last=p->asteroids;
asteroid_t *q=NULL;
g=g+ast->gap;
while(g<ast->gap && last->next!=NULL){
	last=last->next;
}
ast->next=last->next;
ast->prev=last;
last->next=ast;
ast->gap=ast->gap-g;
q=ast->next;
q->gap=q->gap-ast->gap;

No. (Shake)
We should distinguish 2 cases with an [m]if[/m], or actually 4.
It can be that "ast" has to be inserted before the first element of the list, and it can also be that "ast" has to be appended after the last element of the list.
These cases require special handling. (Sweating)
 
  • #70
I like Serena said:
No. (Shake)
We should distinguish 2 cases with an [m]if[/m], or actually 4.
It can be that "ast" has to be inserted before the first element of the list, and it can also be that "ast" has to be appended after the last element of the list.
These cases require special handling. (Sweating)

I added the case where "ast" has to be inserted before the first element of the list and the case where "ast" has to be appended after the last element of the list.

Code:
                asteroid_t *last=p->asteroids;	
	        asteroid_t *q=NULL;
		if(ast->gap<last->gap){
			ast->prev=NULL;
			ast->next=last;
			last->prev=ast;
			last->gap=last->gap-ast->gap;
		}
		g=g+ast->gap;
		while(g<ast->gap && last != NULL){
			last=last->next;
		}
		if(last != NULL && last->next==NULL){
			ast->prev=last;
			ast->next=NULL;
			last->next=ast;
		}
		else{
			ast->next=last->next;
			ast->prev=last;
			last->next=ast;
			ast->gap=ast->gap-g;
			q=ast->next;
			q->gap=q->gap-ast->gap;	
	    }

Is it correct?? (Wondering)
 
  • #71
mathmari said:
Code:
		else{
			ast->next=last->next;
			ast->prev=last;
			last->next=ast;
			ast->gap=ast->gap-g;
			q=ast->next;
			q->gap=q->gap-ast->gap;	
	    }

Is it correct?? (Wondering)

Almost there! (Smile)

In the regular case, 4 connections need to be made (2 next, 2 prev).
I only see 3 connections. (Wasntme)
 
  • #72
I like Serena said:
Almost there! (Smile)

In the regular case, 4 connections need to be made (2 next, 2 prev).
I only see 3 connections. (Wasntme)

Do I have to add [m]last->next->prev=ast[/m] ?? (Wondering)

I made some more changes at the else-statement.

Code:
    else{
                asteroid_t *last=p->asteroids;
                asteroid_t *q=NULL;
                asteroid_t *previous=NULL;
                if(ast->gap<last->gap){
                        ast->prev=NULL;
                        ast->next=last;
                        last->prev=ast;
                        last->gap=last->gap-ast->gap;
                }
                else{
                while(g < ast->gap && last != NULL && last->next != NULL){
	                	g=g+last->gap;
	                	previous=last;
                                last=last->next;
                }
                if(last != NULL && last->next==NULL){
                        ast->prev=last;
                        ast->next=NULL;
                        last->next=ast;
                        ast->gap=ast->gap-g;
                }
                else if(last == NULL){
	                	previous->next=ast;
	                	ast->prev=previous;
	                	ast->next=NULL;
	                	ast->gap = ast->gap - previous->gap;
                }    
                else{
                        ast->next=last->next;
                        last->next->prev=ast;
                        ast->prev=last;
                        last->next=ast;
                        ast->gap=ast->gap-g;
                        q=ast->next;
                        q->gap=q->gap-ast->gap;
            }
        }
    }

When I add the first asteroid ( for example "as"=1, "gap"=10 ) it prints the correct gap.

When I add then a second asteroid ( for example "as"=2, "gap"=25 ) it prints as the gap 25, which is the gap between the asteroid "as"=2 and the object "solid"=101 but it should print the gap between this asteroid "as"=2 and the previous one of the list, which is "as"=1.

Have I done something wrong at the calculation of the gap?? (Wondering)
 
Last edited by a moderator:
  • #73
I changed the while and now it prints 15, which is the gap between the "as"=1 ans the "as"=2 instead of 25!

Code:
while(g < ast->gap && last->next != NULL){
	                g=g+last->gap;
                        last=last->next;
                }
                g=g+last->gap;
(Happy)
 
  • #74
mathmari said:
Do I have to add [m]last->next->prev=ast[/m] ?? (Wondering)

Yes.
And I see you did! (Smile)

When I add the first asteroid ( for example "as"=1, "gap"=10 ) it prints the correct gap.

When I add then a second asteroid ( for example "as"=2, "gap"=25 ) it prints as the gap 25, which is the gap between the asteroid "as"=2 and the object "solid"=101 but it should print the gap between this asteroid "as"=2 and the previous one of the list, which is "as"=1.

Have I done something wrong at the calculation of the gap?? (Wondering)

mathmari said:
I changed the while and now it prints 15, which is the gap between the "as"=1 ans the "as"=2 instead of 25!

Code:
while(g < ast->gap && last->next != NULL){
	                g=g+last->gap;
                        last=last->next;
                }
                g=g+last->gap;
(Happy)

So your gap calculations are okay now? (Wondering)
 
  • #75
I like Serena said:
So your gap calculations are okay now? (Wondering)

Yes! (Yes)(Happy)Now I have to write also an other function. (Nerd)

I have to write a function for the destruction of the planetary system "solid".
With the destruction of the planetary system, the asteroids where the gap between this one and the object, is at least "gap" will also be destructed. (so, they have to be deleted) The asteroids for which the gap is greater are converted to free-floating planets consisting a new collection of free-floating planets (ffplan_t). This new collection should be added to the array of the free-floating planets of the star system to which the planetary system, that is destructed, belonged. The identifier "fp" of the new collection is the identifier of the planetary system that is destructed. The list of the free-floating planets that corresponds to the new collection should be sorted as for the field "as" of the asteroids that are contained. The destructed planetary system should be deleted from the list of planetary systems of the star system to which it belonged.I have done the following:

Code:
int destruction(int solid, int gap){
	int sum=0;
	plansys_t *p=StarS[0].plasy;;
	for(i=0; i<nrStarS; i++){
		p=StarS[i].plasy;
		while (p != NULL && p->solid != solid){
			p=p->next;
		}
	}
	if(p == NULL){
		printf("The planetary system with identifier %d couldn't be found\n", solid);
	}
	asteroid_t *f=p->asteroids;
	while(sum<gap){
		sum=sum+f->gap;
		DELETE(f, as);
		f=f->next;
	}
	
	

	return 0;
}

where the function DELETE() is the following:

Code:
void DELETE(*pointer, int x){
	while(pointer != NULL && pointer->data != x)
		pointer=pointer->next;
	if(pointer == NULL)
		printf("Element %d is not present in the list\n", d);
	if(pointer->prev == NULL && pointer->next != NULL){
		(pointer->next).prev=NULL;
	}
	if(pointer->prev == NULL && pointer->next==NULL){
		pointer=NULL;
	}
	if(pointer->prev != NULL && pointer->next==NULL){
		(pointer->prev).next=NULL;
	}
	else{
		(pointer->prev).next=pointer.next;
		(pointer->next).prev=pointer.prev;
	}
}

Is it correct so far?? (Wondering)
The asteroids for which the gap is greater that "gap" are converted to free-floating planets consisting a new collection of free-floating planets (ffplan_t).

What am I supposed to do at this step?? (Wondering) I got stuck right now...
 
  • #76
The asteroids for which the gap is greater that "gap" are converted to free-floating planets consisting a new collection of free-floating planets (ffplan_t).

Does this mean that I have to insert these asteroids to the list of the free-floating planets?? (Wondering)
 
  • #77
mathmari said:
Code:
void DELETE(*pointer, int x){
	while(pointer != NULL && pointer->data != x)
		pointer=pointer->next;
	if(pointer == NULL)
		printf("Element %d is not present in the list\n", d);
	if(pointer->prev == NULL && pointer->next != NULL){
		(pointer->next).prev=NULL;
	}
	if(pointer->prev == NULL && pointer->next==NULL){
		pointer=NULL;
	}
	if(pointer->prev != NULL && pointer->next==NULL){
		(pointer->prev).next=NULL;
	}
	else{
		(pointer->prev).next=pointer.next;
		(pointer->next).prev=pointer.prev;
	}
}

Is it correct so far?? (Wondering)

That looks a bit complicated, and the memory allocated for the pointer (with calloc) is not actually freed.

How about:
Code:
void DELETE(asteroid_t *pointer, int x){
	while(pointer != NULL && pointer->data != x) {
		pointer=pointer->next;
        }
	if(pointer == NULL) {
		printf("Element %d is not present in the list\n", d);
		return;
        } 
	if(pointer->next != NULL){
		pointer->next->prev=pointer->prev;
	}
	if(pointer->prev != NULL){
		pointer->prev->next = pointer->next;
	}
        free(pointer);
}
(Wondering)

mathmari said:
Does this mean that I have to insert these asteroids to the list of the free-floating planets?? (Wondering)

That appears to be the case. (Wink)
 
  • #78
I like Serena said:
That looks a bit complicated, and the memory allocated for the pointer (with calloc) is not actually freed.

How about:
Code:
void DELETE(asteroid_t *pointer, int x){
	while(pointer != NULL && pointer->data != x) {
		pointer=pointer->next;
        }
	if(pointer == NULL) {
		printf("Element %d is not present in the list\n", d);
		return;
        } 
	if(pointer->next != NULL){
		pointer->next->prev=pointer->prev;
	}
	if(pointer->prev != NULL){
		pointer->prev->next = pointer->next;
	}
        free(pointer);
}
(Wondering)

I see! (Nerd)
I like Serena said:
That appears to be the case. (Wink)

The asteroids for which the gap is greater are converted to free-floating planets consisting a new collection of free-floating planets (ffplan_t). This new collection should be added to the array of the free-floating planets of the star system to which the planetary system, that is destructed, belonged. The identifier "fp" of the new collection is the identifier of the planetary system that is destructed. The list of the free-floating planets that corresponds to the new collection should be sorted as for the field "as" of the asteroids that are contained. The field "gap" of the new list should have the value 0

I tried to insert the asteroids, for which the gap is greater than "gap", to the list of the free-floating planets as followed:

Code:
ffplan_t *fplan=NULL;
	if(f != NULL){
		fplan->fp=solid;
	}
	asteroid_t *planf = calloc(1, sizeof(asteroid_t));
	planf->as=f->as;
	planf->gap=0;
	planf->next=NULL;
	planf->prev=NULL;
	asteroids *K=fplan->ff;
	f-f->next;
	while(f != NULL){
		if (K == NULL) {
        	K = planf;
        } else {
        	asteroid_t *last = K;
        	while (last->next != NULL) {
        		last = last->next;
        	}
        	last->next = planf;
       	}              
		f=f->next;
	}

Is it correct so far?? (Wondering)
 
  • #79
At the following part there must be an error, since I get a segmentation fault, but when I make this part into comments, I don't get any more...

Code:
ffplan_t *fplan=NULL;
	if(f != NULL){
		fplan->fp=solid;
	}
	asteroid_t *planf = calloc(1, sizeof(asteroid_t));
	planf->as=f->as;
	planf->gap=0;
	planf->next=NULL;
	planf->prev=NULL;
	asteroid_t *K=fplan->ff;
	f-f->next;
	while(f != NULL){
		if (K == NULL) {
        	K = planf;
        } else {
        	asteroid_t *last = K;
        	while (last->next != NULL) {
        		last = last->next;
        	}
        	last->next = planf;
       	}              
		f=f->next;
	}

Could you tell me what I have done wrong?? (Wondering)
 
  • #80
mathmari said:
At the following part there must be an error, since I get a segmentation fault, but when I make this part into comments, I don't get any more...

Code:
ffplan_t *fplan=NULL;
	if(f != NULL){
		fplan->fp=solid;
	}
	asteroid_t *planf = calloc(1, sizeof(asteroid_t));
	planf->as=f->as;
	planf->gap=0;
	planf->next=NULL;
	planf->prev=NULL;
	asteroid_t *K=fplan->ff;
	f-f->next;
	while(f != NULL){
		if (K == NULL) {
        	K = planf;
        } else {
        	asteroid_t *last = K;
        	while (last->next != NULL) {
        		last = last->next;
        	}
        	last->next = planf;
       	}              
		f=f->next;
	}

Could you tell me what I have done wrong?? (Wondering)

Well...
You write
Code:
ffplan_t *fplan=NULL;
	if(f != NULL){
		fplan->fp=solid;
	}
Now I'm not sure what "fplan" and "f" are representing.
Perhaps you can clarify? (Wondering)

Either way, if [m]f != NULL[/m], then the code code assigns "solid" to [m]fplan->fp[/m]... but at this point [m]fplan[/m] is NULL. :eek:
So that would give a segmentation fault. (Crying)
 
  • #81
I like Serena said:
Well...
You write
Code:
ffplan_t *fplan=NULL;
	if(f != NULL){
		fplan->fp=solid;
	}
Now I'm not sure what "fplan" and "f" are representing.
Perhaps you can clarify? (Wondering)

"f" is a pointer that points to the list p->asteroids

[m]asteroid_t *f=p->asteroids;[/m]
The asteroids for which the gap is greater are converted to free-floating planets consisting a new collection of free-floating planets (ffplan_t). This new collection should be added to the array of the free-floating planets of the star system to which the planetary system, that is destructed, belonged. The identifier "fp" of the new collection is the identifier of the planetary system that is destructed.
We want to add the asteroids, where the "gap" is greater than gap, to the list of free-floating planets.
That's why I used the pointer "fplan". (Tmi)
I like Serena said:
Either way, if [m]f != NULL[/m], then the code code assigns "solid" to [m]fplan->fp[/m]... but at this point [m]fplan[/m] is NULL. :eek:
So that would give a segmentation fault. (Crying)

How can I insert these asteroids to the list of free-floating planets?? (Wondering)
 
Last edited by a moderator:
  • #82

Attachments

  • star.png
    star.png
    10.5 KB · Views: 102
  • #83
I like Serena said:
It should be: [m]starsystem->plasy=starsystem->Sentinel;[/m].

I am looking again at the program and I have a question... (Nerd)

Code:
int Initialization() {
	int i;
	for(i=0; i<N; i++){
		StarS[i].ss=INT_MAX;
		StarS[i].plasy=NULL;
		StarS[i].ffplan[i].fp=INT_MAX;
		StarS[i].ffplan[i].ff=NULL;
		StarS[i].Sentinel=NULL;
	}
	return 0;
}
int Constitution(int ss) {
1.        int i;
2.        starsy_t *starsystem;
        
3.        if(Sfreep<N){
4.        	starsystem = &StarS[Sfreep];
5.        	Sfreep++;
6.		}
		
7.		if(Sfreep>=N){
8.			return -1;
9.		}
        
10.        starsystem->ss = ss;
11.        starsystem->plasy=starsystem->Sentinel;
12.	for(i=0; i<max; i++){
13.		starsystem->ffplan[i].fp=INT_MAX;
14.		starsystem->ffplan[i].ff=NULL;
15.	}
16.	return (Sfreep - 1);
17.}
At the line 11 of the function Constitution() we set [m]starsystem->plasy=starsystem->Sentinel;[/m] but at the function Initialization() we set [m]StarS.Sentinel=NULL;[/m].

Should we maybe change the value of [m]starsystem->Sentinel[/m] in the function Constitution()?? (Wondering)
Because in that way we set [m]starsystem->plasy[/m] to [m]NULL[/m].
 
  • #84
mathmari said:
I am looking again at the program and I have a question... (Nerd)

Code:
int Initialization() {
		StarS[i].ffplan[i].fp=INT_MAX;
		StarS[i].ffplan[i].ff=NULL;
}

Let's start with this. (Worried)
There should be a nested loop to iterate over [m]ffplan[/m], for instance with the index [m]j[/m].
Otherwise, we're not initializing everything, and moreover, we'll likely get an access violation. (Devil)
Code:
int Constitution(int ss) {
11.        starsystem->plasy=starsystem->Sentinel;
17.}

At the line 11 of the function Constitution() we set [m]starsystem->plasy=starsystem->Sentinel;[/m] but at the function Initialization() we set [m]StarS.Sentinel=NULL;[/m].

Should we maybe change the value of [m]starsystem->Sentinel[/m] in the function Constitution()?? (Wondering)
Because in that way we set [m]starsystem->plasy[/m] to [m]NULL[/m].


Yep.
The [m]Sentinel[/m] is handled the wrong way. (Worried)
It is supposed to be a pointer to the last element in the list, which initially does not exist.

We should set both [m]plasy[/m] and [m]Sentinel[/m] to [m]NULL[/m] (or leave them as NULL). (Wasntme)
 
  • #85
I like Serena said:
Let's start with this. (Worried)
There should be a nested loop to iterate over [m]ffplan[/m], for instance with the index [m]j[/m].
Otherwise, we're not initializing everything, and moreover, we'll likely get an access violation. (Devil)

You're right! (Tmi)

So, is it as followed??

Code:
int Initialization() {
	int i, j;
	for(i=0; i<N; i++){
		StarS[i].ss=INT_MAX;
		StarS[i].plasy=NULL;
		for(j=0; j<max; j++){
			StarS[i].ffplan[i].fp=INT_MAX;
			StarS[i].ffplan[i].ff=NULL;
		}
		StarS[i].Sentinel=NULL;
	}
	return 0;
}

(Wondering)
I like Serena said:
Yep.
The [m]Sentinel[/m] is handled the wrong way. (Worried)
It is supposed to be a pointer to the last element in the list, which initially does not exist.

We should set both [m]plasy[/m] and [m]Sentinel[/m] to [m]NULL[/m] (or leave them as NULL). (Wasntme)

Should it be as followed?? (Wondering)

Code:
int Constitution(int ss) {
        int i;
        starsy_t *starsystem;
        
        if(Sfreep<N){
        	starsystem = &StarS[Sfreep];
        	Sfreep++;
		}
		
		if(Sfreep>=N){
			return -1;
		}
        
        starsystem->ss = ss;
        starsystem->plasy=NULL;
        starsystem->Sentinel=NULL;
	for(i=0; i<max; i++){
		starsystem->ffplan[i].fp=INT_MAX;
		starsystem->ffplan[i].ff=NULL;
	}
	return (Sfreep - 1);
}

At which point do we change its value so that it points to the last element in the list?? (Wondering)
 
  • #86
mathmari said:
You're right! (Tmi)

So, is it as followed?? (Wondering)

Yep! Much better! (Happy)
Should it be as followed?? (Wondering)

Yep! (Wink)
At which point do we change its value so that it points to the last element in the list?? (Wondering)

Whenever we add an element, or remove an element, we need to take into account that [m]plasy[/m], [m]Sentinal[/m], or both need to be updated. (Sweating)
 
  • #87
I like Serena said:
Whenever we add an element, or remove an element, we need to take into account that [m]plasy[/m], [m]Sentinal[/m], or both need to be updated. (Sweating)

Do you mean for example at the following function??

Code:
int Beginning(int solid, int ss){
		int i, k=-1;
        /* Add a planetary system to the list of the planetary system of the star system */
        plansys_t *plansystem = calloc(1, sizeof(plansys_t));
        
        plansystem->solid=solid;
        plansystem->asteroids=NULL;
        plansystem->next=NULL;
		for(i=0; i<Sfreep; i++){
			if(StarS[i].ss==ss){
				k=i;
				if (StarS[k].plasy == NULL) {
                     /* List is empty: replace with new plansystem */
                     StarS[k].plasy = plansystem;
                } else {
                    /* Find last node */
                    plansys_t *last = StarS[k].plasy;
                    while (last->next != NULL) {
                          last = last->next;
                    }
                    /* Append new plansystem to the last node */
                    last->next = plansystem;
                    /* last->next->next=last; */
               }
               StarS[k].Sentinel=StarS[k].plasy;
			}
		}
		return k;
}

(Wondering)
 
  • #88
mathmari said:
Code:
int Beginning(int solid, int ss){
    ...
			if(StarS[i].ss==ss){
				k=i;
				if (StarS[k].plasy == NULL) {
                     /* List is empty: replace with new plansystem */
                     StarS[k].plasy = plansystem;
                } else {
                    /* Find last node */
                    plansys_t *last = StarS[k].plasy;
                    while (last->next != NULL) {
                          last = last->next;
                    }
                    /* Append new plansystem to the last node */
                    last->next = plansystem;
                    /* last->next->next=last; */
               }
               StarS[k].Sentinel=StarS[k].plasy;
			}

Almost... (Thinking)

Now you are always setting the Sentinal to the first node, but it should be the last node. (Wasntme)

Hmm, it would help if there were some consistency to the indentation... (Wink)
 
  • #89
I like Serena said:
Almost... (Thinking)

Now you are always setting the Sentinal to the first node, but it should be the last node. (Wasntme)

Is it maybe as followed??

Code:
int Beginning(int solid, int ss){
		int i, k=-1;
        /* Add a planetary system to the list of the planetary system of the star system */
        plansys_t *plansystem = calloc(1, sizeof(plansys_t));
        
        plansystem->solid=solid;
        plansystem->asteroids=NULL;
        plansystem->next=NULL;
		for(i=0; i<Sfreep; i++){
			if(StarS[i].ss==ss){
				k=i;
				if (StarS[k].plasy == NULL) {
                     /* List is empty: replace with new plansystem */
                     StarS[k].plasy = plansystem;
                     StarS[k].Sentinel=StarS[k].plasy;
                } else {
                    /* Find last node */
                    plansys_t *last = StarS[k].plasy;
                    while (last->next != NULL) {
                          last = last->next;
                    }
                    /* Append new plansystem to the last node */
                    last->next = plansystem;
                    last->next->Sentinel=last;
               }
			}
		}
		return k;
}

(Wondering)

I like Serena said:
Hmm, it would help if there were some consistency to the indentation... (Wink)

What do you mean?? (Wondering)
 
  • #90
mathmari said:
Is it maybe as followed?? (Wondering)

The first is correct! (Smile)

But the second is not. (Worried)
Sentinal is a data member of StarS[k], and not of last->next.
You should set StarS[k].Sentinal to last->next, which is by now the same as plansystem.Alternatively, you could do at the end: [m]StarS[k].Sentinal = plansystem[/m].
That works because [m]plansystem[/m] is always added to the end, wherever that is. So afterwards it is the last node in the list, which is where [m]Sentinal[/m] should point. (Nerd)
What do you mean?? (Wondering)

The way the code is indented, it is hard to follow the flow of the program, and understand if and where something is wrong and should be changed. (Sweating)

Better is:
Code:
int Beginning(int solid, int ss){
    int i, k = -1;
    /* Add a planetary system to the list of the planetary system of the star system */
    plansys_t *plansystem = calloc(1, sizeof(plansys_t));
    
    plansystem->solid = solid;
    plansystem->asteroids = NULL;
    plansystem->next = NULL;
    for(i=0; i<Sfreep; i++){
        if(StarS[i].ss == ss){
            k=i;
            if (StarS[k].plasy == NULL) {
                /* List is empty: replace with new plansystem */
                StarS[k].plasy = plansystem;
                StarS[k].Sentinel = StarS[k].plasy;
            } else {
                /* Find last node */
                plansys_t *last = StarS[k].plasy;
                while (last->next != NULL) {
                    last = last->next;
                }
                /* Append new plansystem to the last node */
                last->next = plansystem;
                last->next->Sentinel = last;
            }
        }
    }
    return k;
}

Like this it becomes clear where the for-loop starts and ends, where the first if-statement is, and where the nested if-else statement is (and that there is one). (Whew)
 
  • #91
I like Serena said:
The first is correct! (Smile)

But the second is not. (Worried)
Sentinal is a data member of StarS[k], and not of last->next.
You should set StarS[k].Sentinal to last->next, which is by now the same as plansystem.Alternatively, you could do at the end: [m]StarS[k].Sentinal = plansystem[/m].
That works because [m]plansystem[/m] is always added to the end, wherever that is. So afterwards it is the last node in the list, which is where [m]Sentinal[/m] should point. (Nerd)

Do you mean that we could write it as followed??

Code:
int Beginning(int solid, int ss){
        int i, k=-1;
        /* Add a planetary system to the list of the planetary system of the star system */
        plansys_t *plansystem = calloc(1, sizeof(plansys_t));
        
        plansystem->solid=solid;
        plansystem->asteroids=NULL;
        plansystem->next=NULL;
	for(i=0; i<Sfreep; i++){
		if(StarS[i].ss==ss){
			k=i;
			if (StarS[k].plasy == NULL) {
                                   /* List is empty: replace with new plansystem */
                                   StarS[k].plasy = plansystem;
                        } else {
                                    /* Find last node */
                                    plansys_t *last = StarS[k].plasy;
                                    while (last->next != NULL) {
                                             last = last->next;
                                    }
                                    /* Append new plansystem to the last node */
                                    last->next = plansystem;
                        }
                        StarS[k].Sentinal = plansystem;
                }
        }
	return k;
}

(Wondering)
I like Serena said:
The way the code is indented, it is hard to follow the flow of the program, and understand if and where something is wrong and should be changed. (Sweating)

Better is:
Code:
int Beginning(int solid, int ss){
    int i, k = -1;
    /* Add a planetary system to the list of the planetary system of the star system */
    plansys_t *plansystem = calloc(1, sizeof(plansys_t));
    
    plansystem->solid = solid;
    plansystem->asteroids = NULL;
    plansystem->next = NULL;
    for(i=0; i<Sfreep; i++){
        if(StarS[i].ss == ss){
            k=i;
            if (StarS[k].plasy == NULL) {
                /* List is empty: replace with new plansystem */
                StarS[k].plasy = plansystem;
                StarS[k].Sentinel = StarS[k].plasy;
            } else {
                /* Find last node */
                plansys_t *last = StarS[k].plasy;
                while (last->next != NULL) {
                    last = last->next;
                }
                /* Append new plansystem to the last node */
                last->next = plansystem;
                last->next->Sentinel = last;
            }
        }
    }
    return k;
}

Like this it becomes clear where the for-loop starts and ends, where the first if-statement is, and where the nested if-else statement is (and that there is one). (Whew)

Ok! (Blush)
 
  • #92
mathmari said:
Do you mean that we could write it as followed?? (Wondering)

Yep! (Nod)
 
  • #93
mathmari said:
The structures have the following form:

View attachment 3540

I am looking again at the program and I got stuck...

Code:
asteroid_t *p=StarS[k].plasy->asteroids;
while(p != NULL && p->as != as){
		p=p->next;
}
if(p != NULL && p->as == as){
		k=i;				
}
After [m]p=p->next;[/m] where does [m]p[/m] point?? At the next node of the planetary system, plasy, or the next asteroid?? (Wondering)
 
  • #94
Hey! :o

mathmari said:
After [m]p=p->next;[/m] where does [m]p[/m] point?? At the next node of the planetary system, plasy, or the next asteroid?? (Wondering)

Code:
asteroid_t *p=StarS[k].plasy->asteroids;

After the initial assignment, [m]p[/m] points to the first asteroid of the first planetary system of star system [m]k[/m].

Code:
while(p != NULL && p->as != as){
		p=p->next;
}

After p=p->next, p points to the next asteroid of the first planetary system. (Nerd)
 
  • #95
Ok! (Malthe)

To find the asteroid with identifier "as" in the star system I had written the following part:

Code:
	int i, k=-1;
	asteroid_t *p=NULL;
	asteroid_t *ast=NULL;
	for(i=0; i<Sfreep; i++){
			ast=StarS[i].plasy->asteroids;
			while(ast != NULL && ast->as != as){
				ast=ast->next;
			}
			if(ast != NULL && ast->as == as){
				k=i;				
			}
	}

	if(k == -1){
		return -1;
	}
		
	p=StarS[k].plasy->asteroids;
	
	if(p == NULL){
		return -1;
	}

But in this way do we not look only the asteroids of the first planetary system?? (Wondering)

Should it be as followed??

Code:
	for(i=0; i<Sfreep; i++){
                        Plan_Syst=StarS[i].plasy;
                        while(Plan_Syst != NULL){ 
                                ast=Plan_Syst->asteroids;
			        while(ast != NULL && ast->as != as){
				        ast=ast->next;
			        }
			        if(ast != NULL && ast->as == as){
				        k=i;	
                                        A=ast;			
			       }
                               Plan_Syst=Plan_Syst->next; 
	                }
        }
	if(k == -1){
		return -1;
	}
		
	p=A;
	
	if(p == NULL){
		return -1;
	}

(Wondering)
 
  • #96
mathmari said:
Ok! (Malthe)

But in this way do we not look only the asteroids of the first planetary system?? (Wondering)

Should it be as followed??

(Wondering)

Yep. To search all asteroids it should be like that. (Wasntme)
 
  • #97
I like Serena said:
Yep. To search all asteroids it should be like that. (Wasntme)

Ok! (Malthe) I have also an other question...
I like Serena said:
Code:
int nrStarS = 0;

int Constitution(int ss) {
        int i;

        // Add a star system to the the array of stars
        starsy_t *starsystem = &StarS[nrStarS];
        nrStarS++;

        // Initialize the new star system
        starsystem->ss = ss;
        starsystem->plasy=StarS[i].Sentinel;
	for(i=0; i<max; i++){
		starsystem->ffplan[i].fp=INT_MAX;
		starsystem->ffplan[i].ff=NULL;
	}

        // Return the index of the star system that was added
	return (nrStarS - 1);
}

int main(){
	Constitution(12);
	for(i=0; i<nrStarS; i++){
		printf("The elements are: %d \n", StarS[i].ss);
	}
	return 0;
}

Could you explain to me why we write [m]starsystem = &StarS[nrStarS];[/m] and not [m]&StarS[nrStarS]=starsystem[/m] ?? (Wondering)
 
  • #98
mathmari said:
Could you explain to me why we write [m]starsystem = &StarS[nrStarS];[/m] and not [m]&StarS[nrStarS]=starsystem[/m] ?? (Wondering)

The structure [m]StarS[nrStarS][/m] is an entry in a global array. Its address is fixed and cannot change. That means it makes no sense to try and assign anything to [m]&StarS[nrStarS][/m].

The pointer [m]starsystem[/m] is a helper variable. We let it point to the location of [m]StarS[nrStarS][/m], so that we can manipulate it more easily, and so that the code reads better. That's why we assign the address [m]&StarS[nrStarS][/m] to it. (Nerd)
 
  • #99
I like Serena said:
The structure [m]StarS[nrStarS][/m] is an entry in a global array. Its address is fixed and cannot change. That means it makes no sense to try and assign anything to [m]&StarS[nrStarS][/m].

The pointer [m]starsystem[/m] is a helper variable. We let it point to the location of [m]StarS[nrStarS][/m], so that we can manipulate it more easily, and so that the code reads better. That's why we assign the address [m]&StarS[nrStarS][/m] to it. (Nerd)

How can the array [m]StarS[/m] have the value of the new starsystem at the position nrStarS, when we assign the [m]&StarS[nrStarS][/m] to [m]starsystem[/m] ?? (Wondering)

[m]nrStarS[/m] is the first free position of the array, so if we assign [m]&StarS[nrStarS][/m] to the new [m]starsystem[/m] doesn't it get the value [m]NULL[/m] ?? (Wondering)
 
Back
Top