Inserted value failing to show up in list

Hey,
I have created a Nodes2 class which has properties value, next, and previous. I am trying to create an insert function that can insert a node with the corresponding properties at any point in the doubly linked list. The DLL class only has the property head and is a handle class. My issue is that my inserted value won't add to the original list. Assume I have pushed 10 elements into the list, and I want to insert value 0 at position 3,
m = DLL();
for i = 1:10
m.push(i)
end
m.insert(m.head.next,0);
function insert(obj,previous, item)
if (nan(previous))
fprintf("The previous node does not exist.\n")
return;
end
% create new node with item
newNode = Nodes2(item);
% set the next and previous of the new node
newNode.next = previous.next;
previous.next = newNode;
newNode.previous = previous;
% change the next nodes previous node
if (isa(newNode.next, 'Nodes2'))
newNode.next.previous = newNode;
fprintf("\ndone\n");
end
node = obj.head;
fprintf("\nForward Traversal: ");
while (isa(node, 'Nodes2'))
fprintf(" {%d}",node.value);
node = node.next;
end
Note: nan is a function I wrote but works similar to isnan!
I am not sure where my logic is wrong. When I print within the function what the previous, and next values are, everything is in check. But when i print my entire list, the 0 has not been inserted.
Let me know your thoughts,
thanks!

15 Comments

" nan is a function I wrote but works similar to isnan!"
My first thought is "Do NOT alias builtin function nan!". If you need isnan, use it; there can be no good come from doing this.
It was a recommended solution on my previous question.
OK, it seems to be an allowed override for a user-defined class...I don't write classes so not all that familiar with those intricacies.
But I see
m.insert(m.head.next,0);
looks to be the calling statement, but the insert method appears to need three arguments
function insert(obj,previous, item)
and there are only two?
if somehow that isn't the issue, I'm guessing only way anybody here could help debug would be to have enough of the class to be able to actually run the code themselves...
the argument count should not be the issue, the fact that it is called as m.insert(b,c) is the same as insert(m,b,c).
If by "the whole list" you mean the Value property, then I don't see any assignment to that property in your insert function?
Also as a side note, perhaps to avoid the overloading issue (I agree with dpb), why not define it as a method of the class so you can disambiguate?
Good point on the .Value; my eyes tend to glaze over with classes stuff...
I wonder about the nan thing still and functionality; "nan" creates a value the in IEEE cannot be tested by the "==" operator; the above description says this implementation acts somewhat like "isnan" which doesn't seem to be at all consistent -- I didn't delve into the doc referred to in previous answer from @Steven Lord suggesting its use, but it just doesn't seem consistent here to what I would presume is a way to build an equivalent of a NaN for a user class to instead have it return the logical.
It probably isn't the culprit here, but it just doesn't smell like the proper use or what was intended directly.
classdef DLL < handle
properties
head; % head node of the DLL
end
methods
function obj = DLL()
obj.head = nan;
end
end
end
classdef Nodes2
properties
value % the value that will be stored in our DLL
previous % pointer to previous node
next % pointer to next node
end
methods
end
function obj = Nodes2(item)
obj.value = item;
obj.next = nan;
obj.previous = nan;
end
end
Hmm, so Nodes2 creates a new node with the item associated with the value.
The nan function is within Nodes2 and essentially if the element is a node then it looks at the value, if it is not a node, it looks at the element directly.
It was a recommended solution on my previous question.
I'm the one who made that suggestion, but my suggestion was not to overload nan to behave like isnan. Rereading I see that I didn't clearly indicate that my suggestion had two pieces. Sorry about that.
  • First, overload nan for your class and have that overload return an object that represents a "missing" or "empty" node.
  • Separately, overload isnan for your class so that it returns true for one of those "missing" or "empty" nodes created by the nan overload.
The datetime class does something like this, though instead of overloading nan and isnan it defines similar functions NaT (Not a Time, like NaN is Not a Number) and isnat. Datetime arrays can use that to indicate a "missing" date and time.
dt = NaT
dt = datetime
NaT
isnat(dt)
ans = logical
1
ismissing(dt)
ans = logical
1
A = [datetime('yesterday'); datetime('today'); datetime('tomorrow'); dt]
A = 4×1 datetime array
04-Oct-2022 05-Oct-2022 06-Oct-2022 NaT
I was sure that was more along the lines of the intent, Steven!!! :)
Thank you for the advice. I will try it that way. I am still unsure why insert isn't updating 'm' to contain the inserted node. Any thoughts?
As @J. Alex Lee notec, your nsert method never sets .Value and I don't see any default action that would do it, either.
I got it. It turns out that Nodes2 needs to be a handle class in order to update 'm' which also comes from a handle class. I do not fully understand the scope of why that is though.
On the nan question, I admit I did not check the previous question/answer, but i just tested that
ismissing(nan)
ans = logical
1
so why wouldn't you just use ismissing and not change anything (or maybe change the constructor to default to missing instead of nan) instead of overload isnan to treat the case of missing, which you will generate by overloading nan?
dpb
dpb on 5 Oct 2022
Edited: dpb on 5 Oct 2022
I'm guessing he'd run into the same issue that led to the above -- there is no footprint for his class for ismissing just as there wasn't for isnan.
Now, there's probably some other way to build the class to work around it, but I'm too old a dog for those new tricks so I've never delved into using user-defined classes or formal oop; we designed and built NSS Savannah and the Oconee class reactors with procedural code and FORTRAN; that's good enough for me! <VBG>
If Nodes2 were a handle class then I would not have gone anywhere near redefining nan() and isnan() or ismissing(): instead of using isnan(dt) I would simply use is ~isvalid(dt)

Sign in to comment.

Answers (1)

Hi Manaal,
I understand that you are trying to define a function that takes in a node from a doubly linked list and inserts a new node right after the given node in that doubly linked list.
One aspect of the code you can inspect further are the addresses of the nodes. If the new node is not being inserted in the right place, I suspect the previous and next nodes are not being mapped properly. This would explain why the new node’s value is not printed when you run through the entire doubly linked list.
Another reason could be that you are dealing with variables that have different scope. This could result in the code not updating the main HEAD node object of the doubly linked list.
Also, please note that I can only speculate why the code is not behaving as expected as I don’t have access to the entire code and am not aware of the other operations you might be performing.

Asked:

on 5 Oct 2022

Answered:

on 8 Sep 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!