Linked List implementation using Javascript - 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);

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

Problems when printing a circular singly linked list

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();

Reverse a linked list... what is wrong with my implementation?

I'm having trouble reversing a linked list based on my implementation below. Is there something wrong or missing that I'm doing here?
class Node {
constructor(val) {
this.val = val;
this.next = null;
}
}
class SinglyLinkedList {
constructor() {
this.head = null;
this.length = 0;
}
push(val) {
var newNode = new Node(val);
var current = this.head;
if (!this.head)
this.head = newNode;
else {
// iterate to the end of the
// list
while (current.next) {
current = current.next;
}
// add node
current.next = newNode;
}
this.length++;
return this;
}
// reverse the list
reverse() {
var prev = null;
var curr = this.head;
while (curr !== null) {
var temp = curr.next;
curr.next = prev;
prev = curr;
curr = temp;
}
return this;
}
print() {
var arr = []
var current = this.head;
while(current) {
arr.push(current.val);
current = current.next;
}
console.log(arr);
}
}
Here's my implementation when I create the object and push some nodes
var list = new SinglyLinkedList();
list.push(1);
list.push(2);
list.push(3);
list.push(4);
Every time I ran list.reverse() then list.print() it only prints [1] only and not [4,3,2,1].
You correctly reverse the links between the nodes, but you never change what this.head is pointing at, so it is now pointing at the end of the list instead of the front of the list. So when you call print, print will start at the last node and then have nowhere to go.
reverse() {
var prev = null;
var curr = this.head;
while (curr !== null) {
var temp = curr.next;
curr.next = prev;
prev = curr;
curr = temp;
}
this.head = prev; // <--- added
return this;
}
You've not updated the head property in your reverse method. Just add this.head = prev; after the while loop and I believe it should work.

How to display to console nodes from linked list

I have a class which creates a link list and also a function that adds nodes to that list . I am trying to implement more functions to the list but I want to see the changes these functions make by displaying the entire list .
this is the code :
function LinkedList() {
var length = 0;
var head = null;
var Node = function(element) {
this.element = element;
this.next = null;
};
this.size = function() {
return length;
};
this.head = function() {
return head;
};
this.add = function(element) {
var node = new Node(element);
if (head === null) {
head = node;
} else {
var currentNode = head;
while (currentNode.next) {
currentNode = currentNode.next;
}
currentNode.next = node;
}
length++;
};
After declaring a LinkedList class and adding elements with the class.add(element) function , how can I display the entire list with console.log() ?
You need to write the toString method of the LinkedList class. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
You could define a method toString in prototype object and loop through all the items.
function LinkedList() {
var length = 0;
var head = null;
var Node = function(element) {
this.element = element;
this.next = null;
};
this.size = function() {
return length;
};
this.head = function() {
return head;
};
this.add = function(element) {
var node = new Node(element);
if (head === null) {
head = node;
} else {
var currentNode = head;
while (currentNode.next) {
currentNode = currentNode.next;
}
currentNode.next = node;
}
length++;
};
}
LinkedList.prototype.toString = function() {
let head = this.head();
let result = [];
while(head) {
result.push(head.element);
console.log();
head = head.next;
}
return result.join(", ");
}
let list = new LinkedList();
list.add("test");
list.add("test2");
list.add("test3");
console.log(list.toString());

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