Problems when printing a circular singly linked list - javascript

I have a circular singly linked list code:
class Node{
constructor(value){
this.value = value;
this.next = null;
}
}
class LinkdeList{
constructor(){
this.first = null;
this.last = null;
}
empty(){
return this.first === null
}
insert(value){
let newest = new Node(value);
if (this.empty()) {
this.first = this.last = newest;
this.last.next = this.first;
}else{
newest.next = this.first;
this.first = newest;
this.last.next = this.first;
}
}
traverse(){
let aux = this.first;
while (aux.next != this.first) {
console.log(aux.value);
aux = aux.next;
}
}
}
let linked = new LinkdeList();
linked.insert("David");
linked.insert("John");
linked.insert("Adam")
linked.insert("Bob");
linked.traverse();
And when I tried to print the list, I just get in console 3 names:
Bob
Adam
John
And as you can see I push 4 names in my linked list. I tried to print the values of my list in the traverse method, but It didn´t work because I don´t get in console:
Bob
Adam
John
David

The loop stops one step too early. This is a good case for a do ... while loop. You should also protect it from failing when the list is empty
traverse() {
if (this.empty()) return; // <---
let aux = this.first;
do {
console.log(aux.value);
aux = aux.next;
} while (aux != this.first);
}
Some other remarks on your code:
As in a non-empty circular list it is always true that the head follows after the tail, it is actually not needed to maintain a first reference. Just keep a last reference, knowing that you can always get the head of the list via last.next.
console.log should not be used in a class method for anything else than debugging. Give your traverse method more flexibility by making it a generator. That way you leave the decision of what to do with the values to the caller of that method.
As in a circular list a node should never have a next property with a null value, don't assign null in the Node constructor. Instead give it a self-reference.
Name the empty method isEmpty as it more clearly indicates that this will not empty the list, but will return whether it is empty.
Fix a typo in the class name: LinkedList
class Node {
constructor(value) {
this.value = value;
this.next = this; // self-reference
}
}
class LinkedList {
constructor() {
this.last = null; // No need for a `first`
}
isEmpty() {
return this.last === null;
}
insert(value) {
const newest = new Node(value);
if (!this.isEmpty()) {
newest.next = this.last.next;
this.last.next = newest;
}
this.last = newest;
}
*traverse() { // Generator
if (this.isEmpty()) return; // Guard
let aux = this.last;
do {
aux = aux.next;
yield aux.value; // Don't print. Yield instead.
} while (aux != this.last);
}
}
const linked = new LinkedList();
linked.insert("David");
linked.insert("John");
linked.insert("Adam")
linked.insert("Bob");
// Caller of traverse can decide what to do: we want to print:
for (const name of linked.traverse()) console.log(name);

Your code works perfectly fine! You just need to tweak your traversal() method because the while loop breaks before it gets a chance to log the last node.
You can try something like this:
traverse(){
let aux = this.first;
while (true) {
console.log(aux.value);
aux = aux.next;
if (aux == this.first) {
break;
}
}
}

I will expand an attribute (count)
constructor() {
...
this.count = 0;
}
Calculate it when insert is called
insert(value) {
...
this.count = this.count + 1;
}
If there is an extension removal method later, remember to calculate it
remove() {
...
this.count = this.count - 1;
}
And adjust the conditional expression of traverse,
replace while (aux.next != this.first) with for (let i = this.count; i > 0; i--)
I prefer trincot's answer, my answer is aimed at a small scope of
code changes.
In practice I will design it with a similar structure(trincot's answer).
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
class LinkdeList {
constructor() {
this.count = 0;
this.first = null;
this.last = null;
}
empty() {
return this.first === null
}
insert(value) {
let newest = new Node(value);
if (this.empty()) {
this.first = this.last = newest;
this.last.next = this.first;
} else {
newest.next = this.first;
this.first = newest;
this.last.next = this.first;
}
this.count = this.count + 1;
}
traverse() {
let aux = this.first;
for (let i = this.count; i > 0; i--) {
console.log(aux.value);
aux = aux.next;
}
}
}
let linked = new LinkdeList();
linked.insert("David");
linked.insert("John");
linked.insert("Adam")
linked.insert("Bob");
linked.traverse();

Related

Problem printing Linked List Item in Javascript

I want to print all of my linked List item using Javascript. Here I create Node class for this. But My printlist() method prints undifined. Can any one help me?
Here Is my Code:
class Node {
constructor(data) {
this.data = data;
this.next = null;
this.head = null;
}
setNextNode(node) {
this.next = node;
}
getNextNode() {
return this.next;
}
printlist() {
let newhead = this.head;
let output = " ";
while (newhead !== null) {
output += newhead.data + ' ';
console.log(output);
newhead = newhead.getNextNode(this.next);
}
}
}
const n1 = new Node(1);
const n2 = new Node(2);
const n3 = new Node(3);
n1.next = n2;
n2.next = n3;
//console.log(n1);
console.log(n1.printlist());
in your constructor, you should set a value for this.head (something like this or this.next).
class Node {
constructor(data) {
this.data = data;
this.next = null;
this.head = this;
}
setNextNode(node) {
this.next = node;
}
getNextNode() {
return this.next;
}
printlist() {
let newhead = this.head;
let output = " ";
while (newhead !== null) {
output += newhead.data + ' ';
console.log(output);
newhead = newhead.getNextNode(this.next);
}
}
}
const n1 = new Node(1);
const n2 = new Node(2);
const n3 = new Node(3);
n1.next = n2;
n2.next = n3;
//console.log(n1);
console.log(n1.printlist());
The problem is that your node's head reference is null, so the loop in printList will not loop.
The concept of head is not one that belongs to the Node class, but to a container class. It is a reference to a first node, so it shouldn't be a property of every node.
I would also not have a printList method, but make the list iterable. That way it becomes much more flexible, and printing becomes very easy for the caller.
Here is how to do that:
class Node {
constructor(data, next=null) { // Allow optional argument
this.data = data;
this.next = next;
// No head property here
}
}
class LinkedList {
constructor() {
this.head = null; // Here we want a head reference
}
prepend(data) {
this.head = new Node(data, this.head);
}
*[Symbol.iterator]() { // Make a list iterable
let node = this.head;
while (node) {
yield node.data;
node = node.next;
}
}
}
const list = new LinkedList();
list.prepend(3);
list.prepend(2);
list.prepend(1);
console.log(...list); // This will call the iterator method

Linked List implementation using Javascript

me and my partner have an issue. in the addToTail method we end by reassigning veryEndResult to newNode (veryEndResult = newNode).
What we were actually trying to do is reassign the value of veryEndResult (this.head.next) to newNode, is there a way to do this? We couldn't google it either because we don't really know how to go about forming that question.
Would love if an experienced coder could help us out on this.
class LinkedList {
constructor () {
this.head = null;
this.length = 0;
}
addToHead (data) {
const newNode = new LinkedListNode(data, this.head);
this.head = newNode;
this.length ++;
return true;
}
addToTail (data) {
const newNode = new LinkedListNode(data, null);
let test = ['this','head'];
this.length ++;
for (let i = 0 ; i < this.length - 1 ; i++) {
test.push('next');
}
let endResult = test.join('.');
let veryEndResult = eval(endResult);
console.log(endResult);
veryEndResult = newNode;
}
}
class LinkedListNode {
constructor (value, next) {
this.value = value;
this.next = next;
}
}
let linkedList = new LinkedList();
linkedList.addToHead(20);
linkedList.addToTail(30);

inserting single node to linked list giving me circular at the next value?

inserting single node to linked list giving me circular at the next value !!
hello there , i am learning how to create a linked list and test it with jest ,
as you can see in the photo my issue that its not stopping , from my understanding it should giving me a null at the end !
this how my conole.log looks like !
my test file :
'use strict' ;
const LL = require('../lib/linked-list.js');
describe('Linked-List Test' , () => {
it('Can properly insert into the linked list' , () => {
let list = new LL() ;
list.insert('test');
expect(list.head.name).toEqual('test');
});
});
my js file :
'use strict';
// const Node = require
function Node(value) {
this.name = value;
this.next = null;
}
class LinkedList {
constructor() {
this.head = null;
}
insert(value) {
let node = new Node(value);
if (!this.head) {
this.head = node;
}
// { name : test1 , next = null }
let pointer = this.head;
console.log(pointer);
console.log(pointer.next);
while (pointer.next) {
pointer = pointer.next;
}
console.log(node);
pointer.next = node;
console.log(pointer.next);
console.log(pointer.next.next);
console.log(pointer.next.next.next);
console.log(pointer.next.next.next.next);
return this;
}
include(value){
let pointer = this.head;
while (pointer.next) {
if(pointer.next.name === value){
return true ;
}
pointer = pointer.next;
}
return false ;
}
}
module.exports = LinkedList;
Try this. You have to add return in if (!this.head) condition. So it should not execute the code after this block.
"use strict";
// const Node = require
function Node(value) {
this.name = value;
this.next = null;
}
class LinkedList {
constructor() {
this.head = null;
}
insert(value) {
let node = new Node(value);
if (!this.head) {
this.head = node;
return this;
}
let pointer = this.head;
while (pointer.next) {
pointer = pointer.next;
}
pointer.next = node;
return this;
}
include(value) {
let pointer = this.head;
while (pointer.next) {
if (pointer.next.name === value) {
return true;
}
pointer = pointer.next;
}
return false;
}
}
let list = new LinkedList();
list.insert("test");
list.insert("test2");
console.log(list);

Make a private member without using Instance Ids Javascript

I have a LinkedList class and I want to make the head member of the instance private. I see how I could create a key id for each instance and those hide the member of users of the LinkedList class. Looking for some other way to make this.head private
function LinkedList() {
this.head = null;
};
LinkedList.prototype = (function () {
function reverseAll(current, prev) {
if (!current.next) { //we have the head
this.head = current;
this.head.next = prev;
}
var next = current.next;
current.next = prev;
reverseAll(next, current);
};
return {
constructor: LinkedList,
reverse: function () {
reverseAll(this.head, null);
},
head: function() {
return this.head;
}
}
})();
LinkedList.prototype.add = function(value) {
var node = {
value: value,
next: null
};
var current;
if (this.head === null) {
this.head = node;
} else {
current = this.head;
while (current.next) {
current = current.next;
}
current.next = node;
}
return node;
}
LinkedList.prototype.remove = function(node) {
var current, value = node.value;
if (this.head !== null) {
if (this.head === node) {
this.head = this.head.next;
node.next = null;
return value;
}
//find node if node not head
current = this.head;
while (current.next) {
if (current.next === node) {
current.next = node.next;
return value;
}
current = current.next;
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(function() {
var obj = new LinkedList();
for (var i = 1; i <= 10; i++) {
obj.add(i);
}
console.log(obj.head);
obj.head = 'pwned';
console.log(obj.head);
});
</script>
The only way I can think of is some sort of abomination like this:
function LinkedList() {
let head = null;
// Instead of using a prototype, you attach the methods directly to this.
// This makes the methods unique per instance, so you can attach privately
// scoped variables (like head).
this.reverse = function() {
// You may use head here.
};
this.head = function() { ... };
}
However, this is highly inefficient as you'll create an entirely new set of closures with each invocation.
Even solutions like the module pattern (or the revealing module pattern) suffer from this problem. If you aren't creating too many of this object, the above example might be for you.

Circular linked list in javascript

I am trying to implement circular linked list in javascript.
I just want to know is it the right way to implement this in javascript?
Are there any memory leaks or infinite object creation?
function LinkedList() {
this.Node = null;
this.count = 0;
this.head = null;
};
LinkedList.prototype.append = function (value) {
// create new node
var node = this.createNode(value);
console.log(value);
if (this.head == null) {
this.Node = node;
this.Node.next = null;
this.head = this.Node;
} else {
var ptr = this.Node;
while (ptr.next != null) {
ptr = ptr.next;
}
ptr.next = node;
}
this.count++;
};
LinkedList.prototype.getSize = function () {
console.log(this);
};
LinkedList.prototype.close = function () {
var ptr = this.head;
while (ptr.next != null) {
ptr = ptr.next;
}
ptr.next = this.head;
};
LinkedList.prototype.createNode = function (value) {
var node = {};
node.value = value;
node.next = null;
return node;
};
var li = new LinkedList();
li.append(1);
li.append(2);
li.append(3);
li.append(4);
li.close();
li.getSize();
When i checked the console, it displayed as head contains one node, and that node contains another node etc.
It it the reference or the actual object they are storing?
The way you did your append function seems slightly flawed to me... because exactly after it executes, your list is at an inconsistent state. You need to call close() in order to setup everything correctly. What i would suggest is that you can alter the append() function to dynamically update the head and tail according; thus you wouldn't need to call close().
Below is how I would have implemented the append() method (basically just slightly modifying your code):
LinkedList.prototype.append = function(value) {
var node = {
value: value,
next: this.head
};//cricular node
if (this.count === 0) {
this.head = {};
this.head.value = value;
this.head.next = this.head;
this.tail = this.head;
} else {
this.tail.next = node;
this.tail = node;
}
this.count++;
};
getCircular(start){
let i=0,j=0;
let secondHead = this.head;
let pointer = this.head;
let pointer2 = secondHead;
while(i<start){
let temp1 = pointer.next;
pointer = temp1;
i++;
}
this.head = pointer;
this.tail.next = pointer2;
while(j<start-1){
let temp2 = pointer2.next;
pointer2 = temp2;
j++;
}
this.tail = pointer2;
this.tail.next = null;
return this;
}
Suppose there is already a list as : Kohli -> Dhoni -> Yuvi -> Sharma -> Dhawan ,
And you pass an index of 2 , then the result will be like :
Yuvi -> Sharma -> Dhawan -> Kohli -> Dhoni
Then your call should be like : ll.getCircular(2); // ll is an object for example

Categories

Resources