Make a private member without using Instance Ids Javascript - 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.

Related

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.

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

LinkedList - Creating function that takes a value, creates a node, and add it to end of list

This is the pseudocode we have to build the LL from:
FUNCTION push(element)
CREATE node
SET node.value TO element
SET node.next TO null
IF the head node does not exist
THEN SET head to node
ELSE
SET current to head
SET current.next to node
END IF
END FUNCTION
The pseudocode itself has an error in it as well.
Below is my attempt to follow that, but right now it's pointing
to the { right after value in the push function.
let head = null,
last,
node,
current,
value = element;
const linkedList = () => {
let node = new Node(value);
push(value) {
if(head === null) {
head = last = node;
} else {
last.next = node;
last = node;
}
}
}
Error : push(value) { <----- This curly bracket is throwing the error. Unexpected token.
Beside the syntax error, you have a logical error as well. You need to treat the head node different from any other node and set the head property to node if not set, but if set, then assign to the last node the next node.
If you no head node, you can not set the last node, because there is actually no one.
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
this.last = null;
}
push(value) {
var node = new Node(value);
if (!this.head) {
this.head = node;
} else {
this.last.next = node;
}
this.last = node;
}
}
var ll = new LinkedList;
ll.push(10);
console.log(ll);
ll.push(11);
console.log(ll);
ll.push(12);
console.log(ll);
.as-console-wrapper { max-height: 100% !important; top: 0; }
With check for an already inserted value.
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
this.last = null;
}
push(value) {
var node = new Node(value),
temp = this.head;
while (temp) {
if (temp.value === value) return;
temp = temp.next;
}
if (!this.head) {
this.head = node;
} else {
this.last.next = node;
}
this.last = node;
}
}
var ll = new LinkedList;
ll.push(10);
console.log(ll);
ll.push(11);
console.log(ll);
ll.push(12);
console.log(ll);
ll.push(11);
console.log(ll);
.as-console-wrapper { max-height: 100% !important; top: 0; }
And since we are at it.
Here is a version where you can insert append and remove nodes in ES6. No last node thougth since that would ruin the beauty of it. :)
class Node {
constructor(value) {
this.prev = null;
this.next = null;
this.value = value === undefined? null : value;
this.list = null;
}
remove() {
let prev = this.prev;
let next = this.next;
if (prev) {
prev.next = next;
}
if (next) {
next.prev = prev;
}
return this;
}
insert(node) {
let prev = this.prev;
if (prev) {
prev.next = node;
node.prev = prev;
}
this.prev = node;
node.next = this;
}
append(node) {
let next = this.next;
if (next) {
next.prev = node;
node.next = next;
}
this.next = node;
node.prev = this;
}
}
class LinkedList {
constructor() {
this.head = null;
}
get last() {
return this.list.length > 0 ? this.list[this.list.length] : null;
}
get values() {
let node = this.head;
let values = [];
while(node) {
values.push(node.value);
node = node.next;
};
return values;
}
push(node) {
node.prev = null;
node.next = null;
if (this.head) {
this.head.prev = node;
node.next = this.head;
}
this.head = node;
}
find(v) {
let node = this.head;
let fn = v;
if (!(v instanceof Function)) fn = (el) => el.value === v;
while(node && !fn(node)) {node = node.next;};
return node;
}
forEach(fn) {
let node = this.head;
while(node) {fn(node); node = node.next;};
}
}
Usable like so:
let ll = new LinkedList();
let n1= new Node(1);
let n2= new Node(2);
let n3= new Node(3);
ll.push(n1);
ll.push(n2);
ll.find(1).append(n3);
console.log(ll.values);
ll.find(3).remove();
console.log(ll.values);
ll.find(2).append(n3);
console.log(ll.values);

Reverse Linked List using Iteration in Javascript

I am getting the desired output i.e the reversed linkedlist on the 3rd iteration in the console.log below.
But I have return previous and it still returns the value from the 1st Iteration.
Even console.log(previous) instead of return previous, gives the desired output.
But now the question is how to display it in the end?
Can someone please explain, what's wrong?
reverse(){
var current= this.head,previous=null;
while(current)
{
var next = current.next;
current.next = previous;
previous = current;
current = next;
console.log(previous); //I am getting my answer at the third iteration
}
return previous; //
}
class LinkedList {
constructor() {
this.head = null;
this.length = 0;
}
add(value) {
var node = new Node(value);
if (this.head == null) {
this.head = node;
this.length++;
} else {
var current = this.head;
while (current.next) {
current = current.next;
}
current.next = node;
this.length++;
}
}
reverse() {
var current = this.head,
previous = null;
while (current) {
var next = current.next;
current.next = previous;
previous = current;
current = next;
console.log(previous);
}
return previous;
}
}
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
var ll = new LinkedList();
ll.add(3);
ll.add(2);
ll.add(7);
ll.reverse();
console.log(ll.head);
It was giving the desired output on return previous
All that was needed was to call the function ll.reverse() or console.log(ll.reverse()) for this specific question.
class LinkedList {
constructor() {
this.head = null;
this.length = 0;
}
add(value) {
var node = new Node(value);
if (this.head == null) {
this.head = node;
this.length++;
} else {
var current = this.head;
while (current.next) {
current = current.next;
}
current.next = node;
this.length++;
}
}
reverse() {
var current = this.head,
previous = null;
while (current) {
var next = current.next;
current.next = previous;
previous = current;
current = next;
}
return previous;
}
}
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
var ll = new LinkedList();
ll.add(3);
ll.add(2);
ll.add(7);
ll.add(9);
console.log(ll.reverse());

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