dastal
Version:
Data Structures & Algorithms implementations
88 lines • 2.93 kB
JavaScript
;
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