📌  相关文章
📜  合并JavaScript中链表的排序(1)

📅  最后修改于: 2023-12-03 15:37:09.882000             🧑  作者: Mango

合并JavaScript中链表的排序

在JavaScript中,我们可以利用对象表示链表的节点,通过每个节点引用下一个节点的方式,构成一个链表。当需要对多个链表进行排序并合并时,我们可以采用归并排序的思路,将链表分割成更小的部分,逐步合并为一个有序的链表。

归并排序实现

归并排序的实现分为分割子链表和合并子链表两个部分。

首先,我们需要编写函数 splitList ,该函数用于分割链表。输入一个链表头部节点,对链表进行分割,返回两个链表的头部节点。

function splitList(head) {
  if (!head || !head.next)
    return head;
  let slow = head, fast = head.next;
  while (fast) {
    fast = fast.next;
    if (fast) {
      slow = slow.next;
      fast = fast.next;
    }
  }
  let head2 = slow.next;
  slow.next = null;
  return head2;
}

接下来,我们需要编写函数 mergeList ,该函数用于合并两个已排好序的链表。输入两个链表的头部节点,将两个链表合并成一个有序的链表,并返回该链表的头部节点。

function mergeList(head1, head2) {
  let dummy = new ListNode(-1);
  let curr = dummy;
  while (head1 && head2) {
    if (head1.val < head2.val) {
      curr.next = head1;
      head1 = head1.next;
    } else {
      curr.next = head2;
      head2 = head2.next;
    }
    curr = curr.next;
  }
  if (head1) curr.next = head1;
  if (head2) curr.next = head2;
  return dummy.next;
}

最后,我们可以在归并排序函数中递归调用 splitListmergeList 函数,实现链表的排序和合并。

function mergeSortList(head) {
  if (!head || !head.next)
    return head;
  let head2 = splitList(head);
  let left = mergeSortList(head);
  let right = mergeSortList(head2);
  return mergeList(left, right);
}
示例代码
function ListNode(val) {
  this.val = val;
  this.next = null;
}

function splitList(head) {
  if (!head || !head.next)
    return head;
  let slow = head, fast = head.next;
  while (fast) {
    fast = fast.next;
    if (fast) {
      slow = slow.next;
      fast = fast.next;
    }
  }
  let head2 = slow.next;
  slow.next = null;
  return head2;
}

function mergeList(head1, head2) {
  let dummy = new ListNode(-1);
  let curr = dummy;
  while (head1 && head2) {
    if (head1.val < head2.val) {
      curr.next = head1;
      head1 = head1.next;
    } else {
      curr.next = head2;
      head2 = head2.next;
    }
    curr = curr.next;
  }
  if (head1)
    curr.next = head1;
  if (head2)
    curr.next = head2;
  return dummy.next;
}

function mergeSortList(head) {
  if (!head || !head.next)
    return head;
  let head2 = splitList(head);
  let left = mergeSortList(head);
  let right = mergeSortList(head2);
  return mergeList(left, right);
}

// 示例测试
let n1 = new ListNode(4);
let n2 = new ListNode(2);
let n3 = new ListNode(1);
let n4 = new ListNode(3);
n1.next = n2;
n2.next = n3;
n3.next = n4;
console.log(mergeSortList(n1)); // 输出: 1 -> 2 -> 3 -> 4 -> null
总结

在JavaScript中,我们可以利用对象表示链表,并通过归并排序对多个链表进行排序和合并。归并排序的实现需要分为分割子链表和合并子链表两个部分,在编写过程中需要考虑到链表为空和只有一个节点的情况。