UNPKG

dastal

Version:

Data Structures & Algorithms implementations

88 lines 2.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.linkedMergeSorted = exports.linkedMergeSort = void 0; /** * Sorts a list in place. * * Works on complete lists as well as sublists and circular lists: * - Linked lists will keep the link to the next node beyond the sorted section * - Doubly linked lists will keep links to the prev and next nodes outside the sorted section * * @param node - The head of the list * @param len - The length of the list beginning from node * @param isDoubly - Whether node is a doubly linked node * @param compareFn - A function used to determine the order of elements. * * It is expected to return: * - A negative value if first argument < second argument * - Zero if first argument == second argument * - A positive value if first argument > second argument * * @returns The new head and tail of the sorted list * * @internal */ function linkedMergeSort(node, len, isDoubly, compareFn) { // Base case if (len < 2) { return [node, node]; } // Split the list into two halves and sort them len = len / 2; const lens = [Math.ceil(len), Math.floor(len)]; const heads = linkedMergeSort(node, lens[0], isDoubly, compareFn); const tails = linkedMergeSort(heads[1].next, lens[1], isDoubly, compareFn); // Group the heads and tails together node = heads[1]; heads[1] = tails[0]; tails[0] = node; tails[0].next = tails[1].next; // Merge the sorted halves const prev = heads[0].prev; node = linkedMergeSorted(heads, lens, isDoubly, compareFn); if (isDoubly) { node.prev = prev; } // Return the head and tail return [node, tails[+(lens[0] < 1)]]; } exports.linkedMergeSort = linkedMergeSort; /** * Merges two sorted lists. * * @param nodes - The heads of the lists * @param lens - The lengths of the lists * @param isDoubly - Whether the lists are a doubly linked * @param compareFn - A function used to determine the order of elements. * * It is expected to return: * - A negative value if first argument < second argument * - Zero if first argument == second argument * - A positive value if first argument > second argument * * @returns The new head of the sorted list * * @internal */ function linkedMergeSorted(heads, lens, isDoubly, compareFn) { const root = {}; let node = root; do { const index = +(compareFn(heads[0].value, heads[1].value) > 0); node.next = heads[index]; if (isDoubly) { node.next.prev = node; } node = node.next; heads[index] = node.next; --lens[index]; } while (lens[0] > 0 && lens[1] > 0); // Add any remaining nodes node.next = heads[+(lens[0] < 1)]; if (isDoubly && node.next) { node.next.prev = node; } return root.next; } exports.linkedMergeSorted = linkedMergeSorted; //# sourceMappingURL=utils.js.map