class LinkedList{
constructor(value) {
const newNode = new Node(value)
this.head = newNode
this.tail = this.head
this.length = 1
}
printList() {
let temp = this.head
while (temp !== null) {
console.log(temp.value)
temp = temp.next
}
}
getHead(){
if(this.head === null) {
console.log('head: null')
} else {
console.log("head: " + this.head.value)
}
}
getTail(){
if (this.tail === null) {
console.log("tail: null")
} else {
console.log('tail: ' + this.tail.value)
}
}
makeEmpty() {
this.head = null
this.tail = null
this.length = 0
}
push(value){
const newNode = new Node(value)
if(!this.head) {
this.head = newNode
this.tail = newNode
} else {
this.tail.next = newNode
this.tail = newNode
}
this.length++
return this
}
pop() {
if (!this.head) return undefined
let temp = this.head
let pre = this.head
while (temp.next) {
pre = temp
temp = temp.next
}
this.tail = pre
this.tail.next = null
this.length--
//最后一个元素pop出去后,要让头尾两个指针指向null
if (this.length === 0){
this.head = null
this.tail = null
}
return temp
}
//前加方法
unshift(value){
const newNode = new Node(value)
if (!this.head) {
this.head = newNode
this.tail = newNode
} else {
newNode.next = this.head
this.head = newNode
}
this.length++
return this
}
shift(){
if(!this.head) return undefined
let temp = this.head
this.head = this.head.next
temp = null
this.length--
if (this.length === 0) {
this.tail = null
}
return temp
}
get(index) {
if (index < 0 || index >= this.length) {
return undefined
}
let temp = this.head
for (let i = 0
temp = temp.next
}
return temp
}
set(index, value) {
let temp = this.get(index)
if (temp) {
temp.value = value
return true
}
return false
}
insert(index, value){
if (index === 0) return this.unshift(value)
if (index === this.length) return this.push(value)
if (index < 0 || index > this.length) return false
const newNode = new Node(value)
const temp = this.get(index - 1)
newNode.next = temp.next
temp.next = newNode
this.length++
return true
}
delete(index) {
if (index === 0) return this.unshift()
if (index === this.length - 1) return this.pop()
if (index < 0 || index > this.length) return undefined
const before = this.get(index - 1)
const temp = before.next
before.next = temp.next
temp.next = null
length--
return temp
}
reverse() {
let temp = this.head
//先头尾翻转
this.head = this.tail
this.tail = temp
// 三个指针,prev,temp,next往前走
let next = temp.next
let prev = null
for (let i = 0
next = temp.next
temp.next = prev
prev = temp
temp = next
}
}
//找到中间的节点,慢指针速度比快指针速度慢一倍。
findMiddleNode() {
let slow = this.head
let fast = this.head
while (fast !== null && fast.next !==null) {
slow = slow.next
fast = fast.next.next
}
return slow
}
//还是快慢指针,因为快指针更快,如果一旦快慢指针指到一个位置,
//那么肯定是有环了
hasLoop() {
let slow = this.head
let fast = this.head
while (fast !== null && fast.next !== null) {
slow = slow.next
fast = fast.next.next
if (slow === fast) {
return true
}
}
return false
}
findKthFromEnd(k){
let slow = this.head
let fast = this.head
// fast先移动k步,其实也就是人为制造快指针比慢指针之间具有k的距离
// 这里++i和i++没区别,区别是++i效率高一点点
for (let i = 0
//如果整个链还不如k长,那就返回null
if (fast === null) {
return null
}
fast = fast.next
}
//再让快指针走到最后,只要快指针走,慢指针也走
while (fast !== null) {
slow = slow.next
fast = fast.next
}
//这时 slow就是从后数第k个元素
return slow
}
reverseBetween(m, n){
if (this.head === null) return
const dummy = new Node(0)
dummy.next = this.head
let prev = dummy
for (let i = 0
//让prev走到m - 1这个点
prev = prev.next
}
// 那么,current就是m这个点
let current = prev.next
//在m到n之间进行for循环
for (let i = 0
const temp = current.next
current.next = temp.next
temp.next = prev.next
prev.next = temp
}
this.head = dummy.next
}
partitionList(x) {
if (this.head === null) return
const dummy1 = new Node(0)
const dummy2 = new Node(0)
let prev1 = dummy1
let prev2 = dummy2
let current = this.head
while (current !== null) {
if (current.value < x) {
prev1.next = current
prev1 = current
} else {
prev2.next = current
prev2 = current
}
current = current.next
}
prev2.next = null
prev1.next = dummy2.next
this.head = dummy1.next
}
removeDuplicates () {
const values = new Set()
let previous = null
let current = this.head
while (current !== null) {
if (values.has(current.value)) {
//有这个值的话就把它跳过去
previous.next = current.next
this.length -= 1
} else {
values.add(current.value)
previous = current
}
current = current.next
}
}
}