www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Double link list

reply Joel <joelcnz gmail.com> writes:
I'm trying some code for practice, but it isn't working properly 
- it prints just one number when printing in reverse.

'''
void main() {
	import std.stdio, std.algorithm, std.range, std.conv;
	struct List(T) {
		class Node {
			T value;
			Node next, prev;
			this(T value0) {
				value = value0;
			}
		}
		Node head, tail;
		auto opOpAssign(string op)(T value) if (op == "~") {
			auto newNode = new Node(value);
			if (head is null) {
				head = tail = newNode;
			} else {
				tail.next = newNode;
				tail.next.prev = tail;
				tail = tail.next;
			}
			return this;
		}
		auto opOpAssign(string op)(T[] values) if (op == "~") {
			values.each!(v => this ~= v);
			return this;
		}
		 property {
			bool empty() { return head is null || tail is null; }
			ref auto front() { return head.value; }
			ref auto back() { return tail.value; }			
		}
		void popFront() { head = head.next;  if (head !is null) 
head.prev = null; }
		void popBack() { tail = tail.prev; if (tail !is null) tail.next 
= null; }
		auto save() { return this; }
	}
	auto ints = List!int();
	ints ~= [0,1,2,3,4];
	ints = ints.dropOne;
	writeln(ints);
	writeln(ints.retro); // just prints 4
}
'''
Feb 24 2018
next sibling parent reply TheFlyingFiddle <none none.com> writes:
On Saturday, 24 February 2018 at 09:48:13 UTC, Joel wrote:
 I'm trying some code for practice, but it isn't working 
 properly - it prints just one number when printing in reverse.
I think the problem is here:
 void popFront() { head = head.next;  if (head !is null) 
 head.prev = null; }
 void popBack() { tail = tail.prev; if (tail !is null) tail.next 
 = null; }
Head and tail will point to the same nodes and you are setting the head.prev to null. Which would make the tail.prev null when iterating it backwards. Similarly if you started iterating it backwards and then iterating it forward it would not work.
Feb 24 2018
parent ag0aep6g <anonymous example.com> writes:
On 02/24/2018 11:26 AM, TheFlyingFiddle wrote:
 On Saturday, 24 February 2018 at 09:48:13 UTC, Joel wrote:
[...]
 void popFront() { head = head.next;  if (head !is null) head.prev = 
 null; }
 void popBack() { tail = tail.prev; if (tail !is null) tail.next = null; }
Head and tail will point to the same nodes and you are setting the head.prev to null. Which would make the tail.prev null when iterating it backwards. Similarly if you started iterating it backwards and then iterating it forward it would not work.
To expand on this: The goal of this was apparently to have `popBack` stop before reaching nodes that have already been `popFront`ed. I.e., `retro` should respect the earlier `dropOne`. To do that properly, you can look for `head is tail`. If `head is tail`, the range is at its last element. Doesn't matter if there is another `next` or `prev`. `popFront` and `popBack` can just declare the range as empty then, e.g. by setting `head = null; tail = null;`. So: ---- void popFront() { if (head is tail) { head = null; tail = null; } else head = head.next; } void popBack() { if (head is tail) { head = null; tail = null; } else tail = tail.prev; } ---- Generally, don't change the data's structure in a range. In a range over a linked list, don't touch the links. Also, the `List` here functions both as a container (adding/removing links) and as a range (traversing the links). Separating the two into different types might make it easier to see what a method should be allowed to do.
Feb 24 2018
prev sibling next sibling parent Alex <sascha.orlov gmail.com> writes:
On Saturday, 24 February 2018 at 09:48:13 UTC, Joel wrote:
 I'm trying some code for practice, but it isn't working 
 properly - it prints just one number when printing in reverse.

 [...]
the first writeln destroys the range via popFront, I think. As if you comment it out, the writeln with retro works as expected. This could be helpful: https://forum.dlang.org/post/urgndzaiqblzdscnnbfc forum.dlang.org
Feb 24 2018
prev sibling parent Joel <joelcnz gmail.com> writes:
On Saturday, 24 February 2018 at 09:48:13 UTC, Joel wrote:
 I'm trying some code for practice, but it isn't working 
 properly - it prints just one number when printing in reverse.
[snip] Thanks guys. And I got it working with 'if (head is tail)' etc.
Feb 24 2018