From fb172a947eb5313ede40cd0ff560a715cd86ce75 Mon Sep 17 00:00:00 2001 From: ahnge Date: Thu, 5 Oct 2023 14:57:18 +0630 Subject: [PATCH 1/2] feat: add mergeTwoSortedLinkedLIsts algorithms --- .../Linked-List/MergeTwoSortedLinkedLists.js | 64 +++++++++++++++++++ .../test/MergeTwoSortedLinkedLists.test.js | 54 ++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js create mode 100644 Data-Structures/Linked-List/test/MergeTwoSortedLinkedLists.test.js diff --git a/Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js b/Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js new file mode 100644 index 0000000000..94eb446792 --- /dev/null +++ b/Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js @@ -0,0 +1,64 @@ +import { Node } from './SinglyLinkedList.js' +/** + * A LinkedList-based solution for merging two sorted linked lists into one sorted list. + * + * @param {Node} list1 - The head of the first sorted linked list. + * @param {Node} list2 - The head of the second sorted linked list. + * @returns {Node} - The head of the merged sorted linked list. + * + * @example + * const list1 = new ListNode(1); + * list1.next = new ListNode(2); + * list1.next.next = new ListNode(4); + * + * const list2 = new ListNode(1); + * list2.next = new ListNode(3); + * list2.next.next = new ListNode(4); + * + * const result = mergeLists(list1, list2); + * // Returns the head of a linked list representing 1 -> 1 -> 2 -> 3 -> 4 -> 4 + */ + +class MergeTwoSortedLinkedLists { + mergeLists(list1, list2) { + let dummy = new Node(-1) + let current = dummy + + while (list1 && list2) { + if (list1.val < list2.val) { + current.next = list1 + list1 = list1.next + } else { + current.next = list2 + list2 = list2.next + } + current = current.next + } + + // If one of the lists is not empty, append it to the result + if (list1) { + current.next = list1 + } else if (list2) { + current.next = list2 + } + + return dummy.next + } + + /** + * Converts a linked list to an array. + * + * @param {Node} head - The head of the linked list. + * @returns {number[]} - An array representing the linked list values. + */ + linkedListToArray(head) { + const resultArray = [] + while (head) { + resultArray.push(head.val) + head = head.next + } + return resultArray + } +} + +export { MergeTwoSortedLinkedLists } diff --git a/Data-Structures/Linked-List/test/MergeTwoSortedLinkedLists.test.js b/Data-Structures/Linked-List/test/MergeTwoSortedLinkedLists.test.js new file mode 100644 index 0000000000..aebc3e9175 --- /dev/null +++ b/Data-Structures/Linked-List/test/MergeTwoSortedLinkedLists.test.js @@ -0,0 +1,54 @@ +import { MergeTwoSortedLinkedLists } from '../MergeTwoSortedLinkedLists.js' +import { Node } from '../SinglyLinkedList.js' + +describe('MergeTwoSortedLinkedLists', () => { + it('Merges two sorted linked lists', () => { + const list1 = new Node(1) + list1.next = new Node(2) + list1.next.next = new Node(4) + + const list2 = new Node(1) + list2.next = new Node(3) + list2.next.next = new Node(4) + + const expectedResult = new Node(1) + expectedResult.next = new Node(1) + expectedResult.next.next = new Node(2) + expectedResult.next.next.next = new Node(3) + expectedResult.next.next.next.next = new Node(4) + expectedResult.next.next.next.next.next = new Node(4) + + const merger = new MergeTwoSortedLinkedLists() + const result = merger.mergeLists(list1, list2) + + expect(merger.linkedListToArray(result)).toEqual( + merger.linkedListToArray(expectedResult) + ) + }) + + it('Merges two empty linked lists', () => { + const list1 = null + const list2 = null + + const expectedResult = null + + const merger = new MergeTwoSortedLinkedLists() + const result = merger.mergeLists(list1, list2) + + expect(result).toEqual(expectedResult) + }) + + it('Merges one empty linked list with a non-empty one', () => { + const list1 = null + const list2 = new Node(0) + + const expectedResult = new Node(0) + + const merger = new MergeTwoSortedLinkedLists() + const result = merger.mergeLists(list1, list2) + + expect(merger.linkedListToArray(result)).toEqual( + merger.linkedListToArray(expectedResult) + ) + }) +}) From aa74a76c3b69181ea8b16982c411c6279976fc36 Mon Sep 17 00:00:00 2001 From: ahnge Date: Tue, 10 Oct 2023 11:12:07 +0630 Subject: [PATCH 2/2] remove class and unnecessary function change the function params and return value from Node to LinkedList. --- .../Linked-List/MergeTwoSortedLinkedLists.js | 75 +++++++------------ .../test/MergeTwoSortedLinkedLists.test.js | 57 ++++++-------- 2 files changed, 49 insertions(+), 83 deletions(-) diff --git a/Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js b/Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js index 94eb446792..df11c0ac2c 100644 --- a/Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js +++ b/Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js @@ -1,64 +1,45 @@ -import { Node } from './SinglyLinkedList.js' +import { LinkedList } from './SinglyLinkedList.js' /** * A LinkedList-based solution for merging two sorted linked lists into one sorted list. * - * @param {Node} list1 - The head of the first sorted linked list. - * @param {Node} list2 - The head of the second sorted linked list. - * @returns {Node} - The head of the merged sorted linked list. + * @param {LinkedList} list1 - The the first sorted linked list. + * @param {LinkedList} list2 - The second sorted linked list. + * @returns {LinkedList} - The merged sorted linked list. * * @example - * const list1 = new ListNode(1); - * list1.next = new ListNode(2); - * list1.next.next = new ListNode(4); + * const list1 = new LinkedList([1,2,4]); * - * const list2 = new ListNode(1); - * list2.next = new ListNode(3); - * list2.next.next = new ListNode(4); + * const list2 = new LinkedList([1,3,4]); * - * const result = mergeLists(list1, list2); - * // Returns the head of a linked list representing 1 -> 1 -> 2 -> 3 -> 4 -> 4 + * const result = mergeLinkedLists(list1, list2); + * // Returns the merged linked list representing 1 -> 1 -> 2 -> 3 -> 4 -> 4 */ -class MergeTwoSortedLinkedLists { - mergeLists(list1, list2) { - let dummy = new Node(-1) - let current = dummy +function mergeLinkedLists(list1, list2) { + const mergedList = new LinkedList() - while (list1 && list2) { - if (list1.val < list2.val) { - current.next = list1 - list1 = list1.next + let current1 = list1.headNode + let current2 = list2.headNode + + while (current1 || current2) { + if (!current1) { + mergedList.addLast(current2.data) + current2 = current2.next + } else if (!current2) { + mergedList.addLast(current1.data) + current1 = current1.next + } else { + if (current1.data < current2.data) { + mergedList.addLast(current1.data) + current1 = current1.next } else { - current.next = list2 - list2 = list2.next + mergedList.addLast(current2.data) + current2 = current2.next } - current = current.next - } - - // If one of the lists is not empty, append it to the result - if (list1) { - current.next = list1 - } else if (list2) { - current.next = list2 } - - return dummy.next } - /** - * Converts a linked list to an array. - * - * @param {Node} head - The head of the linked list. - * @returns {number[]} - An array representing the linked list values. - */ - linkedListToArray(head) { - const resultArray = [] - while (head) { - resultArray.push(head.val) - head = head.next - } - return resultArray - } + return mergedList } -export { MergeTwoSortedLinkedLists } +export { mergeLinkedLists } diff --git a/Data-Structures/Linked-List/test/MergeTwoSortedLinkedLists.test.js b/Data-Structures/Linked-List/test/MergeTwoSortedLinkedLists.test.js index aebc3e9175..bc5bea953e 100644 --- a/Data-Structures/Linked-List/test/MergeTwoSortedLinkedLists.test.js +++ b/Data-Structures/Linked-List/test/MergeTwoSortedLinkedLists.test.js @@ -1,54 +1,39 @@ -import { MergeTwoSortedLinkedLists } from '../MergeTwoSortedLinkedLists.js' -import { Node } from '../SinglyLinkedList.js' +import { expect } from 'vitest' +import { mergeLinkedLists } from '../MergeTwoSortedLinkedLists.js' +import { LinkedList } from '../SinglyLinkedList.js' describe('MergeTwoSortedLinkedLists', () => { it('Merges two sorted linked lists', () => { - const list1 = new Node(1) - list1.next = new Node(2) - list1.next.next = new Node(4) - - const list2 = new Node(1) - list2.next = new Node(3) - list2.next.next = new Node(4) - - const expectedResult = new Node(1) - expectedResult.next = new Node(1) - expectedResult.next.next = new Node(2) - expectedResult.next.next.next = new Node(3) - expectedResult.next.next.next.next = new Node(4) - expectedResult.next.next.next.next.next = new Node(4) - - const merger = new MergeTwoSortedLinkedLists() - const result = merger.mergeLists(list1, list2) - - expect(merger.linkedListToArray(result)).toEqual( - merger.linkedListToArray(expectedResult) - ) + const list1 = new LinkedList([1, 2, 4]) + + const list2 = new LinkedList([1, 3, 4]) + + const expectedResult = new LinkedList([1, 1, 2, 3, 4, 4]) + + const result = mergeLinkedLists(list1, list2) + + expect(result).toEqual(expectedResult) }) it('Merges two empty linked lists', () => { - const list1 = null - const list2 = null + const list1 = new LinkedList() + const list2 = new LinkedList() - const expectedResult = null + const expectedResult = new LinkedList() - const merger = new MergeTwoSortedLinkedLists() - const result = merger.mergeLists(list1, list2) + const result = mergeLinkedLists(list1, list2) expect(result).toEqual(expectedResult) }) it('Merges one empty linked list with a non-empty one', () => { - const list1 = null - const list2 = new Node(0) + const list1 = new LinkedList() + const list2 = new LinkedList([1]) - const expectedResult = new Node(0) + const expectedResult = new LinkedList([1]) - const merger = new MergeTwoSortedLinkedLists() - const result = merger.mergeLists(list1, list2) + const result = mergeLinkedLists(list1, list2) - expect(merger.linkedListToArray(result)).toEqual( - merger.linkedListToArray(expectedResult) - ) + expect(result).toEqual(expectedResult) }) })