• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Programming |OT| C is better than C++! No, C++ is better than C

Linkhero1

Member
It's possible that there's a looping way of doing it that they had in mind.

Code:
    StringBuilder firstHalf = new StringBuilder();
    StringBuilder secondHalf = new StringBuilder();
    for (int i = 0; i < (text.length() - 1) / 2; i++) {
      firstHalf.append(text.charAt(i));
      secondHalf.append(text.charAt(text.length() - i - 1));
    }
    String s2 = firstHalf.append(secondHalf.reverse()).toString();

This can probably be done more simply, in fact.

Unfortunately, no. It asked to do this with just concatenation and substring. I just said no If Statements since it's the easier way of doing it :p

The single line solution using just substring, length and integer arithmetic is definitely more awesome, though. :D

Awesome and confusing :)
 

upandaway

Member
Edit: I'm really trying to understand this solution but I become scatterbrained midway through the first substring lol.
If you can understand what I wrote, it's exactly the same, except he's representing the 1 with something that becomes 0 if the string's length is 0.
 

iapetus

Scary Euro Man
If you can understand what I wrote, it's exactly the same, except he's representing the 1 with something that becomes 0 if the string's length is 0.

This is it. x * 2 / (x + 1) evaluates to 0 when x is 0, and 1 when x is any positive integer. This allows us to single out x == 0 as a special case without using a conditional. In this case I used it to add 1 to the indexes if x is 0 and then simplified the expression slightly. Which sometimes has the side effect of making it look more confusing. :)
 

Linkhero1

Member
This is it. x * 2 / (x + 1) evaluates to 0 when x is 0, and 1 when x is any positive integer. This allows us to single out x == 0 as a special case without using a conditional. In this case I used it to add 1 to the indexes if x is 0 and then simplified the expression slightly. Which sometimes has the side effect of making it look more confusing. :)
This is genuinely a clever way of solving the problem. I really want to know what your thought process is when solving problems like this. :p
 

iapetus

Scary Euro Man
This is genuinely a clever way of solving the problem. I really want to know what your thought process is when solving problems like this. :p

It just so happens I remember the thought process I went through. :p

1. First state the problem: the problem is that we need to treat 0 as a special case, but can't do so because we aren't allowed to use if (and I'm not going to use ternary if as a way round that).

2. First approach: if 0 is problematic, ensure that we never have a length 0 string - by adding a dummy character front and end, and removing them after the operation. Unfortunately this leaves us with the same problem in a different way - if we do this for a zero-length string we end up with a zero-length string which we then want to remove the first and last characters from - no good.

3. Right, so for any solution we need to be able to distinguish between zero and non-zero. The easiest way to do this using the constraints we have is to come up with an expression that evaluates to 0 for an input of 0 and 1 for any positive integer input.

4. x / x + 1 looks positive - 0 divided by anything will always be 0, and we divide by x + 1 to avoid the risk of dividing by zero. Unfortunately it doesn't work, because we always round down.

5. x / x + 1 gives us 1/2, 2/3 and other numbers tending towards (but never reaching) 1, which all get rounded down to 0. We want to round to 1. Doubling this value will always give us a range from 1 to not-quite-2, which is exactly what we want.

6. Looking at the errors we were getting before, we need to add 1 if text.length() is zero in one case and subtract it in the other case. So whip up a formula that maps 0 to +1 and 1 to 0, and add or subtract it accordingly.

7. Simplify the expression.
 

Water

Member
Why does he have to do it without if/else statements? That seems like a silly constraint.
In this case, it might be an artificial constraint, but being able to avoid conditional statements is a very good skill to have in general. When you can do it without doing anything silly, your code is likely to be better for it in several ways: more robust, easier to analyze and test, etc. In some environments conditionals are poison for performance - GPU programming in particular.
 

Gartooth

Member
You are attempting to use a dynamically allocated array of node pointers:

Code:
Node** list;

Your first memory allocation allocates space for the array. Since you are using calloc, it also initializes all the data to zero.

And the contents of list look like:

Those are all NULL pointers. You can't do anything with them, because they point to nothing.

If you want to store nodes in the list, you need to replace the null pointers with Node pointers that point to valid memory.

It's up to you whether you want to do this in advance:

or do it on demand:

Thank you for the advice. I managed to complete the program successfully, my issue was pertaining to managing the array size and then going out of bounds when trying to print and free the list.
 

heytred

Neo Member
I've got a quick question (I intended to figure this out myself. I'm sitting in English, but my mind is on Comp Sci), but what would be the best way without using the Java Array class and Arrays.sort() method to organize an array of Objects?

I have an assignment where we have to write various methods for a Phone Directory and it's incredibly simple for them most part, the last problem I have to solve is how to reorganize the array after either of the two methods that remove an object are called (i.e. if I remove the second element in a 10 element array, how can I reorganize it so 0-8 are objects and element 9 is null?)

My current thought process is to write a new method arraySort that transfers the elements (after a removal) to a temp array ( if (!null)) and then copies back into the original?

Is this stupid? Am I on the right thought track? Better ways to do it?
 

iapetus

Scary Euro Man
Do you have to use an array? Using something from the Collections API - an ArrayList or similar - would make this trivial. :)

Here's a quick method to rationalise an array (ie. push all nulls to the end of the array)

Code:
public void rationaliseArray(Object[] array) {
  for (int i = 0; array != null && i < (array.length - 1); i++) {
    if (array[i] == null) {
      array[i] = array[i + 1];
    }
  }
}

Scratch that - doesn't work. :D Needs to be slightly more complex.
 

heytred

Neo Member
Do you have to use an array? Using something from the Collections API - an ArrayList or similar - would make this trivial. :)

Here's a quick method to rationalise an array (ie. push all nulls to the end of the array)

Code:
public void rationaliseArray(Object[] array) {
  for (int i = 0; array != null && i < (array.length - 1); i++) {
    if (array[i] == null) {
      array[i] = array[i + 1];
    }
  }
}

Scratch that - doesn't work. :D Needs to be slightly more complex.

Yeah, for the sake of complexity my professor prevents us from using methods or classes that we haven't discussed in class - even ArrayList.

This is what I wrote just now:

Code:
private static void sortArray() {
		PhoneRecord[] temp = new PhoneRecord[50];
		for(int i = 0, j = 0; i < records.length; i++) {
			if (records[i] != null) {
				temp[j] = records[i];
				j++;
			}
		}
		for (int i = 0; i < records.length; i++) {
			temp[i] = records[i];
		}

	}

I just implemented sortArray(); method call into the two methods that actually remove an object. Does this look like it would work (I was half focusing on English notes).
 

Water

Member
Just tested it and it looks to be working? I'll double check after class. Any input is extremely appreciated!
You are doing the right thing, but don't make a temp array because it's unnecessary.

It's just a matter of keeping track of the first insertion spot with one index, the first read spot with another index, and filling the range from insertion index to end with nulls after the read index runs out of the array.

In general this is a situation solved by a partition algorithm (which separates two categories of objects), but you get away with doing the simpler thing above because one of those categories in this case is 'nulls' which you don't need to store to be able to write them at the end.
 

Linkhero1

Member
It just so happens I remember the thought process I went through. :p

1. First state the problem: the problem is that we need to treat 0 as a special case, but can't do so because we aren't allowed to use if (and I'm not going to use ternary if as a way round that).

2. First approach: if 0 is problematic, ensure that we never have a length 0 string - by adding a dummy character front and end, and removing them after the operation. Unfortunately this leaves us with the same problem in a different way - if we do this for a zero-length string we end up with a zero-length string which we then want to remove the first and last characters from - no good.

3. Right, so for any solution we need to be able to distinguish between zero and non-zero. The easiest way to do this using the constraints we have is to come up with an expression that evaluates to 0 for an input of 0 and 1 for any positive integer input.

4. x / x + 1 looks positive - 0 divided by anything will always be 0, and we divide by x + 1 to avoid the risk of dividing by zero. Unfortunately it doesn't work, because we always round down.

5. x / x + 1 gives us 1/2, 2/3 and other numbers tending towards (but never reaching) 1, which all get rounded down to 0. We want to round to 1. Doubling this value will always give us a range from 1 to not-quite-2, which is exactly what we want.

6. Looking at the errors we were getting before, we need to add 1 if text.length() is zero in one case and subtract it in the other case. So whip up a formula that maps 0 to +1 and 1 to 0, and add or subtract it accordingly.

7. Simplify the expression.
Thank you. I'm starting to understand it much better. I'll start participate in this thread as much as I can.
 

Jokab

Member
Today I learned the horrors of SQL/PSM, and especially PL/SQL. Who thought it was a good idea to not allow subqueries in IF-statements? Took my and my lab partner around 3 hours to figure out, and the incredibly cryptic Oracle error messages didn't make things any better. I suppose the resulting code is more readable since the only solution we could think of was storing the results in variables, but still. Nevertheless, it's in general a pretty horrible language.
 

heytred

Neo Member
You are doing the right thing, but don't make a temp array because it's unnecessary.

It's just a matter of keeping track of the first insertion spot with one index, the first read spot with another index, and filling the range from insertion index to end with nulls after the read index runs out of the array.

In general this is a situation solved by a partition algorithm (which separates two categories of objects), but you get away with doing the simpler thing above because one of those categories in this case is 'nulls' which you don't need to store to be able to write them at the end.

Ah yes, that is definitely much more simple and makes so much more sense. Thank you!

I feel so dumb -_-
 

Granadier

Is currently on Stage 1: Denial regarding the service game future
Ah yes, that is definitely much more simple and makes so much more sense. Thank you!

I feel so dumb -_-

Don't.
You asking that question allowed others to learn.
me

Edit: May I ask what year you're in?

Edit2: iapetus, is the partition algorithm what you were using earlier when you were helping with that substring problem?
Code:
//pseudo-polynomial algorithm
       public static bool balancePatition(int[] S)
       {
           var n = S.Length;
           var N = S.Sum();
           bool[,] P = new bool[N / 2 + 1, n + 1];
           for (int i = 0; i < n + 1; i++)
               P[0, i] = true;
           for (int i = 1; i < N / 2 + 1; i++)
               P[i, 0] = false;
           for (int i = 1; i <= N / 2; i++)
               for (int j = 1; j <= n; j++)
                   P[i, j] = S[j - 1] <= i ? P[i, j - 1] || P[i - S[j - 1], j - 1] : P[i, j - 1];
           return P[N / 2, n];
       }
looks oddly similar to what you were discussing.
 
I want to ask a question about a super simple hw assignment I have (I'm just starting C++), but I'd feel like an asshole after reading the shit you guys are discussing...
 

Rapstah

Member
I want to ask a question about a super simple hw assignment I have (I'm just starting C++), but I'd feel like an asshole after reading the shit you guys are discussing...

Don't feel embarassed. I had to write some PHP at work today for the first time in two or three years and sat around staring at my code for fifteen minutes before I realised lines are supposed to end with semicolons in PHP.
 
Ok, well here goes...

This is the assignment:
t8rVVmg.jpg

This is what I have and I can't for the life of me figure out how to print it right-justified.
Managed to print it inverted, but the required format is stumping me, lol.
Code:
int _tmain(int argc, _TCHAR* argv[])
{
	int line, col;


for (line = 1; line < 11; line++)
{	
for (col = 1; col <= line; col++)
	printf_s( "*");
	printf_s("\n");
}

	printf_s(" ");


	return 0;
}
 

Rapstah

Member
Don't think of it as printing the stars right-justified, think of it as printing less and less spaces followed by more and more stars.
 

Jokab

Member
Ok, well here goes...

This is the assignment:


This is what I have and I can't for the life of me figure out how to print it right-justified.
Managed to print it inverted, but the required format is stumping me, lol.
Code:
code

It's actually quite a tricky problem I thought - I have been going to school for programming for 1,5 years now and I had to give it some serious thought. Don't be disheartened it if takes you a while.
 

Kansoku

Member
It's actually very simple:

If you look closely, the number of '*' on the last line is the same number of lines (10 in this case), so you can make it use only one variable.

Code:
int size;
for(){ //repeat for the number of lines
   for() //repeat for the number of spaces (Hint: the number of spaces is related to the number of the line)
   for() //repeat for the '*'
   //new line
}
 
So I came back, beat my head on the desk for about 30 mins, and gave up for tonight.

This is so frustrating because it seems like it's probably quite obvious and moderately simple, yet I can't wrap my brain around it. Blargh.
 

Water

Member
So I came back, beat my head on the desk for about 30 mins, and gave up for tonight.

This is so frustrating because it seems like it's probably quite obvious and moderately simple, yet I can't wrap my brain around it. Blargh.
Just write code that prints the first line correctly.
When you have that, it's going to be obvious how to expand it to print every line.
 

Granadier

Is currently on Stage 1: Denial regarding the service game future
Just write code that prints the first line correctly.
When you have that, it's going to be obvious how to expand it to print every line.

Exactly this.
Also I find that just writing out in English what my objective is helps as well. Split up your problem, no matter how big, into small parts. Then look at the parts and figure out what you know how to do.

So I came back, beat my head on the desk for about 30 mins, and gave up for tonight.

This is so frustrating because it seems like it's probably quite obvious and moderately simple, yet I can't wrap my brain around it. Blargh.

Listen to Water. I think you will be able to get this.
What does a for loop do?
What do you need to print out?
Utilize the commands your limited to.
  • printf ("*") prints an asterisk
  • printf (" ") prints a space
  • printf ("\n") moves the output to the next line.
Good luck!
 

Hylian7

Member
So I came back, beat my head on the desk for about 30 mins, and gave up for tonight.

This is so frustrating because it seems like it's probably quite obvious and moderately simple, yet I can't wrap my brain around it. Blargh.

Just remember spaces are characters too. Imagine that whole thing as a block of chracters, like this.

Code:
**********
**********
**********
**********
**********
**********
**********
**********
**********
**********

Now make it replace the *'s you don't want to be there with spaces.
 

iapetus

Scary Euro Man
You are doing the right thing, but don't make a temp array because it's unnecessary.

It's just a matter of keeping track of the first insertion spot with one index, the first read spot with another index, and filling the range from insertion index to end with nulls after the read index runs out of the array.

Not sure I'm quite following what you're saying, but can't it be simpler? No need to fill any range with nulls if we do it as we go...

Code:
int firstNull = -1;
for (int i = 0; i < array.length; i++) {
  if (array[i] == null) {
    if (firstNull == -1) {
      firstNull = i;
    }
  } else if (firstNull != -1) {
    array[firstNull++] = array[i];
    array[i] = null;
  }
}
 

Water

Member
Not sure I'm quite following what you're saying, but can't it be simpler? No need to fill any range with nulls if we do it as we go...

Code:
int firstNull = -1;
for (int i = 0; i < array.length; i++) {
  if (array[i] == null) {
    if (firstNull == -1) {
      firstNull = i;
    }
  } else if (firstNull != -1) {
    array[firstNull++] = array[i];
    array[i] = null;
  }
}
You are right, it can be folded into the same loop. I didn't stop to actually think about the code, just gave some drive-by advice.
I find your version a bit hard to understand due to your use of the magic -1 value. I'd prefer something like this.
Code:
for (int in=0, out=0; out < a.length; ++out) {
  while (in < a.length && a[in] != null) ++in; // find next value to read
  a[out] = in < a.length ? a[in] : null; // write it or null if no more values
}
Edit: writing the code like I originally suggested (loop over possible input values and write any non-nulls, then afterwards fill the unwritten space with nulls in a separate loop) is nearly as simple, and I'm sure it would be more efficient since it omits a lot of unnecessary conditionals. So it's not an inferior way either.
 

iapetus

Scary Euro Man
You are right, it can be folded into the same loop. I didn't stop to actually think about the code, just gave some drive-by advice.
I find your version a bit hard to understand due to your use of the magic -1 value. I'd prefer something like this.
Code:
for (int in=0, out=0; out < a.length; ++out) {
  while (in < a.length && a[in] != null) ++in; // find next value to read
  a[out] = in < a.length ? a[in] : null; // write it or null if no more values
}

<shrug> I find your version a lot harder to understand - albeit somewhat more elegant. Suspect it's actually using more conditionals than mine, although they're better concealed. ;) I don't think using a value one less than the lowest array index to indicate a special case is any worse than using a value one more than the highest array index for the same purpose, though I do see where you're coming from there.

I understand what you're getting at with your other approach now, by the way. To borrow your somewhat condensed style (which I don't like - give me whitespace and explicitly marked out blocks any day of the week):

Code:
int out=0;
for (int in = 0; in < a.length; ++in)
if (a[in] != null) a[out++] = a[in];
while (out < a.length) a[out++] = null;

Fewer conditionals, yes. Given how minor any difference in performance is likely to be between the three solutions, I'd go with whichever is clearest. :p
 

Granadier

Is currently on Stage 1: Denial regarding the service game future
Continue arguing you two.

This is wonderful reading how you are both optimizing the methods.
 

iapetus

Scary Euro Man
Continue arguing you two.

This is wonderful reading how you are both optimizing the methods.

Oh, I don't think we're arguing as such, and Water's doing better optimisation than me on this one. :p I suspect the areas where we differ are mostly personal preference, and probably stem from our different coding backgrounds...
 

Granadier

Is currently on Stage 1: Denial regarding the service game future
Oh, I don't think we're arguing as such, and Water's doing better optimisation than me on this one. :p I suspect the areas where we differ are mostly personal preference, and probably stem from our different coding backgrounds...

Arguing was a harsh word to use. I was trying to refer to your back and forth conversation about the problem.

It's a learning experience to read through.
 

Water

Member
<shrug> I find your version a lot harder to understand - albeit somewhat more elegant. Suspect it's actually using more conditionals than mine, although they're better concealed. ;) I don't think using a value one less than the lowest array index to indicate a special case is any worse than using a value one more than the highest array index for the same purpose, though I do see where you're coming from there.
I think my version is more clearly divided into meaningful parts, and makes it more explicit what the state is supposed to be at any point in the execution. In your code the execution jumps around; it took me a while before I was convinced that the code was correct.

Check out how much our solutions mutate state. Inside my loop there's a single assignment and a lone increment. You have three assignments plus an increment embedded into a statement.

Use of the "one-over" index is standard pretty much everywhere, since you need it to be able to properly indicate e.g. an empty range. Using -1 or another magic number is sometimes handy, but when you don't really need it, I think it's strictly worse. My code would use unsigned types for indices if the language wasn't Java (which lacks unsigned types IIRC?).
I understand what you're getting at with your other approach now, by the way. To borrow your somewhat condensed style (which I don't like - give me whitespace and explicitly marked out blocks any day of the week):
...
Fewer conditionals, yes. Given how minor any difference in performance is likely to be between the three solutions, I'd go with whichever is clearest. :p
I don't think I'm condensing the code in a way that reduces readability. (What I'd do differently in actual code would be to stick the comments on their own rows above the code they refer to, and to give the statement inside the while its own row and indent.) For instance, I rarely embed an increment operator inside an expression like you do; I think that's a recipe for trouble.

I'm not a performance guy (and definitely not a Java guy), but I think the null-fill version would allow the compiler to optimize a ton. The amount of statements you see in the code is only half the story. Replacing the final loop with standard library stuff that zeroes out a range in an array could do more still.
 

iapetus

Scary Euro Man
I think my version is more clearly divided into meaningful parts, and makes it more explicit what the state is supposed to be at any point in the execution. In your code the execution jumps around; it took me a while before I was convinced that the code was correct.

I disagree. But then that's hardly a surprise given that I wrote mine and you wrote yours. One property that only my solution has out of the three is that after each iteration of the loop the array contains the same values as it did originally, but with the nulls pushed towards the end of the array somewhat. That can make it a whole load clearer what's going on.

Check out how much our solutions mutate state. Inside my loop there's a single assignment and a lone increment. You have three assignments plus an increment embedded into a statement.

How much state is mutated depends on the contents of the arrays. As the array contains more null values, mine does a lot less mutation than yours. As the array contains fewer null values, mine does a lot more. One extreme case would be where a thousand-entry array contains a single item at the end. Your code would do 2000 assignments; mine would do four. At the other extreme, with the worst case for mine - a thousand-entry array full of items other than a single null at the beginning - your code would do 2000 assignments; mine would do 3001 (I think).

Use of the "one-over" index is standard pretty much everywhere, since you need it to be able to properly indicate e.g. an empty range. Using -1 or another magic number is sometimes handy, but when you don't really need it, I think it's strictly worse. My code would use unsigned types for indices if the language wasn't Java (which lacks unsigned types IIRC?).

-1 for this sort of case is also standard pretty much everywhere. If we weren't using Java, I'd use null instead. I refuse to use Integer as the type to iterate over in Java, though. ;)

I don't think I'm condensing the code in a way that reduces readability. (What I'd do differently in actual code would be to stick the comments on their own rows above the code they refer to, and to give the statement inside the while its own row and indent.) For instance, I rarely embed an increment operator inside an expression like you do; I think that's a recipe for trouble.

You didn't give the while its own line in your earlier code. :p

My experience has been that using single-line if/while/for expressions leads to bugs. You might be able to handle it, but in several large-scale projects with multiple developers I've seen a lot of bad errors as a result of doing that, and no corresponding errors from an excess of braces and whitespace. You don't even get RSI from it any more, as your IDE will put them in for you. :D

Like I said, we've got different stylistic preferences here, I suspect, and there's probably not a definitive 'right' way to do most of these things.

I'm not a performance guy (and definitely not a Java guy), but I think the null-fill version would allow the compiler to optimize a ton. The amount of statements you see in the code is only half the story. Replacing the final loop with standard library stuff that zeroes out a range in an array could do more still.

Less than you might think. It would only happen in cases where the array is sparse, and in those cases my solution wouldn't be doing many writes anyway - the trade off in terms of writes would be between a couple of slow writes and a large number of fast ones. In cases where my solution's doing a large number of writes, there wouldn't be many nulls to write at the end of the array. It probably does best in the mid range of array sparseness.

Edit: And as I think I said earlier, the performance difference between them is probably negligible in most real-world scenarios. They're all O(n), and none of them's doing anything hideous performance-wise. A few assigns here, a few comparisons there, with the advantage going different ways for different arrays; you picks your algorithm and you takes your choice...
 

Water

Member
How much state is mutated depends on the contents of the arrays. As the array contains more null values, mine does a lot less mutation than yours. As the array contains fewer null values, mine does a lot more. One extreme case would be where a thousand-entry array contains a single item at the end. Your code would do 2000 assignments; mine would do four. At the other extreme, with the worst case for mine - a thousand-entry array full of items other than a single null at the beginning - your code would do 2000 assignments; mine would do 3001 (I think).
I pointed towards the individual assignments/mutations in the code because having few of them, and those few ones being in a simple pattern, are what I generally strive for to make my code readable. Actual runtime counts of those operations were not the point.

You can see at a glance that every array item will be written exactly once, in order, unconditionally. Then the only question remaining for correctness is whether the data being written into an individual array item is correct.
 

dave is ok

aztek is ok
That same problem was the second weeks problem in Harvard's online CS program.

I had to get help because nested loops were way beyond me when I tried to do it.

Here is the walkthrough for it. It helps without giving away the answer.

EDIT: Looking at what you have done, this won't help you at all. But oh well :)
 

iapetus

Scary Euro Man
I pointed towards the individual assignments/mutations in the code because having few of them, and those few ones being in a simple pattern, are what I generally strive for to make my code readable. Actual runtime counts of those operations were not the point.

It's likely to be more the point if performance is important, though.

You can see at a glance that every array item will be written exactly once, in order, unconditionally. Then the only question remaining for correctness is whether the data being written into an individual array item is correct.

As opposed to being able to see that when an item needs moving, it will be moved with no possibility that you'll end up leaving the wrong data in the array if you have your pointers pointing to the wrong places. It's often the case that if there are two ways of doing something, one will make some things clearer, and the other will make other things clearer. Unless you're coding in perl, in which case you should strive to make nothing clear. :p
 
Just write code that prints the first line correctly.
When you have that, it's going to be obvious how to expand it to print every line.

So I did what you said and got the first line printing correctly, but it's not quite jumping out at me how to expand the program. Do I need to have three for loops or can it be done with two?
 

tokkun

Member
It's likely to be more the point if performance is important, though.

I worked on some performance-critical projects in the past - things where differences of microseconds of execution time was a big deal - and you might be surprised at how little correct intuition you can get about a program's performance from a metric like 'number of instructions executed', even when you are coding in C++ which is a lot more predictable than Java.

Low-level optimization is usually more about improving IPC than it is about reducing instructions, because a single cache miss is usually enough to hide the execution time of a lot of instructions. Ultimately the lesson I took away from it was that you shouldn't believe low level performance claims without micro-benchmarks, and even then you should take them with a large grain of salt.
 

Korosenai

Member
Just started a data structures class, and i'm having problems with some linked list stuff (doubly linked lists).

I have the add tail function as follows:

Code:
void doublyLinkedList::addTail(Node *n)
{
	if ((head == NULL) && (tail == NULL))
	{
		head = n;
		tail = n;
		n->prev = head;
		n->next = tail;
	}
	else
	{
		tail->next = n;
		n->prev = tail;
		tail = n;
	}
}

The problem arises at the add head function, which doesn't work and the program just stops running.

Code:
void doublyLinkedList::addHead(Node *n)
{
	if ((head == NULL) && (tail == NULL))
	{
		head = n;
		tail = n;
		n->prev = head;
		n->next = tail;
	}
	else
	{
		head->prev = n;
		n->next = head;
		head = n;
	}
}

The input from main.cpp:
Code:
doublyLinkedList *dl = new doublyLinkedList(); 

	Node *n1 = new Node(10);
	dl->addTail(n1);

	Node *n2 = new Node(20);
	dl->addTail(n2);

        dl->displayTail();

	Node *n3 = new Node(30);
	dl->addHead(n3);

I guess the problem is happening here:
Code:
Node *n3 = new Node(30);
	dl->addHead(n3);

The output I get:
Code:
20
10
0

*popup screen

program.exe has stopped working*

Anyone have any idea what's wrong with the code?
 
Maybe when you are adding to a non empty tail or head, you are not defining the next of the new Node (when addTail) and not defining the prev (when addHead) .
 
Top Bottom