JS合并两个排序的链表

925 阅读2分钟

描述: 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

链表的结构

image.png

链表不同于数组,链表是一种上一个元素的引用指向下一个元素的存储结构,链表通过指针来连接元素与元素;

image.png

如图所示为两个链表 L1 和 L2

每个Node节点有 val 和 next 两个部分, val 为当前数据, next 为下一元素指针,应题实现L1和L2的合并且递增排序

思路:处理链表,通过L1,L2 双指针找到对应数据,比较大小,输出到新的链表结构当中

创建新的链表 Res,Head 为虚拟节点 [0, null]

image.png

比较 L1 和 L2 链表第一个元素 val 的大小,得到最小Val的节点,Res 的 next 指针指向该节点

ScreenRecorderProject3.gif

首先用 JS 创建一个链表的数据结构 NodeList

class NodeList {
  constructor(val) {
    this.val = val
    this.next = null
  }

  //添加链表的新增节点方法
  append(val) {
    let currnt = this
    let node = new NodeList(val)
    while (currnt.next) {
      currnt = currnt.next
    }
    currnt.next = node
  }

  // 打印
  print() {
    let current = this
    let res = []
    while (current) {
      res.push(current.val)
      current = current.next
    }
    console.log(res)
  }
}

创建如图所示2个链表:

let node1 = new NodeList(1)
node1.append(2)
node1.append(6)
node1.append(8)


let node2 = new NodeList(3)
node2.append(4)
node2.append(5)
node2.append(9

// 打印
node1.print()
node2.print()

结果:[ 1, 2, 6, 8 ] [ 3, 4, 5, 9 ]

实现:

const f = (n1, n2) => {
  let res = new NodeList(0) //创建虚拟节点
  let p = res // res 指针
  let p1 = n1 // L1 指针
  let p2 = n2 // L2指针

  while (p1 && p2) {
    if (p1.val < p2.val) {
      p.next = p1 // p指针指向 p1
      p1 = p1.next // L1指针右移
    } else {
      p.next = p2 // p指针指向 p2
      p2 = p2.next // L2指针右移
    }
    p = p.next // p 的指针右移
  }
  p.next = p1 ? p1 : p2 // 当前有一个链表已合并历完, p next 指针直接指向未合并的剩余链表的下一个元素


  return res.next
}

测试结果

const res = f(node1, node2) res.print()

输出: [ 1, 2, 3, 4, 5, 6, 8, 9 ]

完整代码:

class NodeList {
  constructor(val) {
    this.val = val
    this.next = null
  }

  //添加链表的新增节点方法
  append(val) {
    let currnt = this
    let node = new NodeList(val)
    while (currnt.next) {
      currnt = currnt.next
    }
    currnt.next = node
  }

  // 打印
  print() {
    let current = this
    let res = []
    while (current) {
      res.push(current.val)
      current = current.next
    }
    console.log(res)
  }
}

const f = (n1, n2) => {
  let res = new NodeList(0) //创建虚拟节点
  let p = res // res 指针
  let p1 = n1 // L1 指针
  let p2 = n2 // L2指针

  while (p1 && p2) {
    if (p1.val < p2.val) {
      p.next = p1 // p指针指向 p1
      p1 = p1.next // L1指针右移
    } else {
      p.next = p2 // p指针指向 p2
      p2 = p2.next // L2指针右移
    }
    p = p.next // p 的指针右移
  }
  p.next = p1 ? p1 : p2 // 当前有一个链表已合并历完, p next 指针直接指向未合并的剩余链表的下一个元素


  return res.next
}

let node1 = new NodeList(1)
node1.append(2)
node1.append(6)
node1.append(8)


let node2 = new NodeList(3)
node2.append(4)
node2.append(5)
node2.append(9)

node1.print()
node2.print()
const res = f(node1, node2)
res.print()

github