class ListNode {
constructor(val) {
this.val = val
this.next = null
}
}
class SingleLinkList {
constructor() {
this.head = null
}
insert(val) {
const node = new ListNode(val)
if (!this.head) {
this.head = node
} else {
let curr = this.head
while (curr.next) {
curr = curr.next
}
curr.next = node
}
}
insertSort(val) {
const node = new ListNode(val)
if (!this.head) {
this.head = node
} else {
let curr = this.head,
pre = curr
while (curr.next && curr.val < val) {
pre = curr
curr = curr.next
}
if (curr.val < val) {
node.next = curr.next
curr.next = node
} else {
if (pre === curr) {
node.next = curr
this.head = node
} else {
node.next = curr
pre.next = node
}
}
}
}
traverse(head = this.head) {
const arr = []
if (!head) return arr
while (head) {
arr.push(head.val)
head = head.next
}
return arr
}
reverse(head = this.head) {
if (!head || !head.next) return true
let pre = null,
temp = null,
curr = head
while (curr) {
temp = curr.next
curr.next = pre
pre = curr
curr = temp
}
this.head = pre
temp = null
return true
}
sortLinkList(head = this.head) {
const dummyHead = new ListNode(0)
dummyHead.next = head
let p = head,
length = 0
while (p) {
++length
p = p.next
}
for (let size = 1; size < length; size <<= 1) {
let curr = dummyHead.next,
tail = dummyHead
while (curr) {
let left = curr,
right = SingleLinkList.cut(left, size)
curr = SingleLinkList.cut(right, size)
tail.next = SingleLinkList.merge(left, right)
while (tail.next) {
tail = tail.next
}
}
}
return (this.head = dummyHead.next)
}
static cut(head, n) {
let p = head
while (--n && p) {
p = p.next
}
if (!p) return null
let next = p.next
p.next = null
return next
}
static merge(l1, l2) {
let dummyHead = new ListNode(0),
p = dummyHead
while (l1 && l2) {
if (l1.val < l2.val) {
p.next = l1
p = p.next
l1 = l1.next
} else {
p.next = l2
p = p.next
l2 = l2.next
}
}
p.next = l1 ? l1 : l2
return dummyHead.next
}
}
;(() => {
const arr = [9, 2, 1, 3, 4, 6, 0, 10, 36, 45, 22, 31]
const linkList = new SingleLinkList()
console.log('----直接插入----')
arr.forEach(e => linkList.insert(e))
console.log('----遍历单链表----')
console.log(linkList.traverse())
console.log('----归并排序----')
linkList.sortLinkList()
console.log('----遍历单链表----')
console.log(linkList.traverse())
})()