📌  相关文章
📜  用于反转单链表中的备用 K 节点的 Javascript 程序(1)

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

反转单链表中的指定节点

本篇文章将向您展示一个使用 JavaScript 编写的程序,用于反转单链表中备用 K 节点(从后往前数第 K 个节点)的位置。

问题背景

在单链表中,反转整个链表或者前N个节点的位置是实现得较容易的。但是在实际问题的解决中,往往需要对单链表中的某些部分进行反转。例如,反转从倒数第K个节点到倒数第M个节点的位置。

解决方案

在解决这个问题之前,我们先从反转整个链表的程序开始思考。

反转整个链表
function reverseLinkedList(head) {
  let prev = null;
  let curr = head;
  while (curr !== null) {
    let next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
  }
  return prev;
}

此程序定义了两个指针:prevcurr。初始化时,prev 是空,curr 指向链表头节点。在循环中,先将 next 定义为 curr 的下一个节点,然后将 currnext 指针指向 prev,再将 prev 设为 currcurr 设为 next。 这个过程会一直进行到 curr 成为 null,即整个链表被反转后成为新的头节点 prev

反转链表中从倒数第 k 个节点到结尾的节点

想要反转到某个节点的话,我们需要知道这个节点的位置。因此,在对链表进行修改前,我们要先不改变链表的结构,利用遍历的方式找到倒数第K个节点的位置。当然,倒数第K个节点和倒数第M个节点的位置需要预先输入。

function reverseKthNode(head, k) {
  let curr = head;
  let prev = null;
  let next = null;
  let tail = null;
  let count = 0;

  while (curr !== null) {
    count++;
    if (count === k) {
      tail = prev;
    }
    if (count > k) {
      tail = tail.next;
    }
    next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
  }

  let newHead = prev;
  let newTail = tail.next;

  while (newTail !== null) {
    tail.next = newTail;
    newTail = newTail.next;
    tail = tail.next;
  }

  return newHead;
}

该程序遍历单链表,并记录下找到的倒数第K个节点。遍历完成后,将反转后的链表和尾节点重新拼接起来返回新的链表头节点。

程序测试
function ListNode(val, next) {
  this.val = val === undefined ? 0 : val;
  this.next = next === undefined ? null : next;
}

let linkedList = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5, null))))); 
console.log(reverseKthNode(linkedList, 2)); // { val: 1, next: { val: 4, next: { val: 3, next: { val: 2, next: { val: 5, next: null } } } } }

以上的程序输出应为 { val: 1, next: { val: 4, next: { val: 3, next: { val: 2, next: { val: 5, next: null } } } } }。可以看到,倒数第二个节点 {val: 4} 和它之后的节点已经被反转,其他节点的顺序不变。

以上便是本文的全部内容,希望对您有所帮助。