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

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.

Related

Working on my first linked list and can't get the return function to work correctly

Here is the code I have gathered and worked on so far. I can't seem to get my remove function to work correctly. It keeps saying "Cannot read properties of undefined (reading 'value') when I try to execute it on the last two lines. Any tips or help would be appreciated, thank you!
function LinkedList() {
this.head = null;
this.tail = null;
this.length = 0;
}
function Node(value) {
this.value = value;
this.next = null;
}
// adds a node to the specified index
// if index is specified, accepts parameter (value, index)
// if no index is specified then add element to the end of list
LinkedList.prototype.add = function(...value) {
if (!this.head) {
this.head = this.tail = new Node(...value);
this.length++;
return;
}
while (value.length) {
let curr = value.pop();
this.tail.next = new Node(curr);
this.tail = this.tail.next;
this.length++;
}
}
// retrieves the node at the specified index
LinkedList.prototype.get = function(index) {
if (index >= this.length) {
return -1;
}
if (index === 0) {
return this.head;
}
let previousNode = null;
let currentNode = this.head;
for (let i = 0; i < index; i++) {
if (!currentNode.next) {
break;
}
previousNode = currentNode;
currentNode = currentNode.next;
}
previousNode.next = currentNode.next;
this.length--;
return currentNode;
}
// retrieves and removes the node at the specified index
// if no index is specified, removes the last node (tail)
LinkedList.prototype.remove = function(index) {
if (this.length === 0) {
return undefined;
}
if (this.head.value === index) {
this.removeFromHead();
return this;
}
let previousNode = this.head;
let thisNode = previousNode.next;
while (thisNode) {
if (thisNode.value === index) {
break;
}
previousNode = thisNode;
thisNode = thisNode.next;
}
if (thisNode === null) {
return undefined;
}
previousNode.next = thisNode.next;
this.length--;
return this;
}
LinkedList.prototype.removeFromHead = function() {
if (this.length === 0) {
return undefined;
}
const value = this.head.value;
this.head = this.head.next;
this.length--;
return value;
}
let linkedList = new LinkedList()
linkedList.add(0);
linkedList.add(1, 0);
linkedList
console.log(linkedList.remove().value) //should return 1
console.log(linkedList.remove().value) //should return 2
I'm not all cuteseed up

LinkedList recursion problem using Javascript

Looking for help solving this recursion problem: Given a linked list of indeterminate length, composed of nodes that store a reference to the next node....how can you return the list in reverse?
For example, node A --> B --> C --> D should return D-->C-->B-->A. The function is given any node and should return that list in reverse.
A node would consist of a couple values; an integer (i) and a next property which is the pointer to the next node.
const traverseList = (node) => {
if(node.next !== null) traverseList(node);
else return;
}
I'm trying this code but it's not working. Just looking for the missing pieces, please. Thanks for any help.
you are on the right path, just print it when you are returning from each node.
const traverseList = (node) => {
if (!node) return;
traverseList(node.next);
console.log(node.value); // or whatever you want to output
}
1) Store a reference to current(initially head), next(initially null), previous(initially null) node
2) Set tail to head, if your using a tail pointer
3) Traverse this list setting next to current.next, current.next to previous, previous to current, and finally current to next
4) Depending on how you do it after the loop, you must set current.next to previous and head to current
I have included both iterative and recursive solutions below.
class Node {
constructor(value, next){
this.value = value;
this.next = next;
}
}
class LinkedList {
constructor(){
this.size = 0;
this.head = null;
this.tail = null;
}
add(value){
const node = new Node(value, null);
if(this.head === null){
this.head = node;
this.tail = node;
} else {
this.tail.next = node;
this.tail = node;
}
this.size++;
}
traverse(){
let current = this.head;
while(current != null){
console.log(current.value);
current = current.next;
}
}
reverse(){
let current = this.head;
let previous = null;
let next = null;
this.tail = current;
while(current != null && current.next != null){
next = current.next;
current.next = previous;
previous = current;
current = next;
}
current.next = previous;
this.head = current;
}
_reverseRecursively(node){
if(node == null){
return null;
}
if(node.next == null){
this.head = node;
return node;
}
let nextNode = this._reverseRecursively(node.next);
nextNode.next = node;
node.next = null;
return node;
}
reverseRecursively(){
this.tail = this.head;
this._reverseRecursively(this.head);
}
}
const list = new LinkedList();
list.add(10);
list.add(12);
list.add(14);
console.log("Original List");
list.traverse();
list.reverse();
console.log("Reversed List - using loop");
list.traverse();
list.reverseRecursively();
console.log("Reversed List - using recursion");
list.traverse();

How to implement methods add(value, index) and remove(index) for the SinglyLinkedList

I need to implement methods for removing and adding items by index. I was able to implement only at the beginning and end of the list. I understand that I have to break an array by index, add a new element to the end of the first list. and then add another part to it? Please help
class Node{
constructor(value, next, prev){
this.value = value;
this.next = next;
this.prev = prev;
}
}
class SinglyLinkedList{
constructor(){
this.head = null;
this.tail = null;
}
addFirst(value){
let node = new Node(value, this.head, null);
if (this.head){
this.head.prev = node;
}
else {
this.tail = node;
}
this.head = node;
}
removeFirst(){
if (!this.head){
return null;
}
let value = this.head.value;
this.head = this.head.next;
if (this.head) {
this.head.prev = null;
}
else {
this.tail = null;
}
return value;
}
toString(){
let str = "";
let current = this.head;
while (current){
str += current.value + " ";
current = current.next;
}
console.log(str.trim());
}
}
The add(value, index) will look like this -
add(value, index){
let node = new Node(value, null, null);
if(!this.head){
this.head = node;
} else if(index == 0) {
node.next = this.head;
this.head = node;
} else {
let current = this.head;
let d = 1;
while(current !== NULL){
if(d === index){
node.next = current.next;
current.next = node;
break;
}
current = current.next;
d++;
}
}
return head;
}
Notice here the algorithm:
Create a new node with given value.
if the this.head is currently NULL then set the new node to this.head
if the given index is 0 then also set the node to this.head
else loop over the linked list and find the right position and set the node there
The remove(index) method will look like this:
remove(index) {
if(!this.head){
return;
}
let temp = this.head;
if(index === 0){
this.head = temp.next;
return;
}
for(let i=0;temp!==null && i<index - 1;i++){
temp = temp.next;
if(temp === null || temp->next === null){
return;
}
let next = temp.next.next;
temp.next = next;
}
}
Notice here the algorithm for remove(index) is also very similar:
if the this.head is not defined yet then return
if the node to be removed is the head then assign new head and return
else loop over the linked list until the position is found then change the next properties to remove the node at the desired position
You can implement removeAtIndex() in the following way :
removeAtIndex(index){
if (!this.head){
return null;
}
var i = 1;
var temp = this.head;
var save;
console.log(temp);
while(i < index && temp){
save = temp;
temp = temp.next;
i++;
}
if(temp){
save.next = temp.next;
} else{
save.next = undefined;
}
return temp.value;
}
Basically just iterate to that index and maintain reference to the node before it and the reference to the node after the index of node which you want to delete. And simply save the reference of next node node which you want to delete in the next of the previous node of the node which you want to delete.
You an implement add in the similar way.
In the snippet removeAtIndex() functionality is demonstrated you can make addAtIndex in the same way.
class Node{
constructor(value, next, prev){
this.value = value;
this.next = next;
this.prev = prev;
}
}
class SinglyLinkedList{
constructor(){
this.head = null;
this.tail = null;
}
addFirst(value){
let node = new Node(value, this.head, null);
if (this.head){
this.head.prev = node;
}
else {
this.tail = node;
}
this.head = node;
}
removeFirst(){
if (!this.head){
return null;
}
let value = this.head.value;
this.head = this.head.next;
if (this.head) {
this.head.prev = null;
}
else {
this.tail = null;
}
return value;
}
removeAtIndex(index){
if (!this.head){
return null;
}
var i = 1;
var temp = this.head;
var save;
while(i < index && temp){
save = temp;
temp = temp.next;
i++;
}
if(temp){
save.next = temp.next;
} else{
save.next = undefined;
}
return temp.value;
}
toString(){
let str = "";
let current = this.head;
while (current){
str += current.value + " ";
current = current.next;
}
console.log(str.trim());
}
}
list = new SinglyLinkedList();
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
list.removeAtIndex(2);
console.log(list.toString());

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