昨天看了面试官: 既然已经有数组了,为什么还要链表,最后留了一道思考题了,自己把链表和数组的方式都实现了一遍,数组实现还是很简单的。链表不是很熟,如有错误或疏忽,敬请指正。
题目是这样的:
我们平时在用的微信小程序会有最近使用的功能,时间最近的在最上面,按照时间顺序往后排,当用过的小程序大于一定数量后,最不常用的小程序就不会出现了,你会如何设计这个算法

链表版
var linkedList = {
head: null,
length: 0,
}
var MAX_LENGTH = 4
var wechatItem = {
name: '微信读书',
id: 'a',
}
var jingDongItem = {
name: '京东到家',
id: 'b'
}
var jueJinItem = {
name: '掘金',
id: 'c'
}
var meiTuanItem = {
name: '美团',
id: 'd'
}
// 添加元素到链表中
function linkedListAppend (list, addItem) {
let current = list.head
if (list.head === null) {
list.head = addItem
} else {
while (current.next) {
current = current.next
}
current.next = addItem
}
list.length += 1
}
// 使用一个微信小程序
function linkedListUse (list, useItem) {
let current = list.head
let isNewItem = false
while (current.next.id !== useItem.id) {
current = current.next
if (!current.next) {
// 查到最后一个都还没有找到
isNewItem = true
break
}
}
if (isNewItem) {
// 使用了新的小程序
useItem.next = list.head
list.head = useItem
list.length += 1
} else {
// 使用的是已经存在的小程序
let changedNode = current.next
let changedNextNode = changedNode.next
let firstNode = list.head
if (current === firstNode) {
// 交换节点为1和2
changedNode.next = firstNode
list.head = changedNode
firstNode.next = changedNextNode
} else {
// if (changedNextNode) {
changedNode.next = firstNode.next
current.next = firstNode
list.head = changedNode
firstNode.next = changedNextNode
}
}
// 超出最大长度后面就不再显示
if (list.length > MAX_LENGTH) {
let current = list.head
let count = 0
while (current.next) {
count += 1
if (count === MAX_LENGTH) {
current.next = null
list.length = MAX_LENGTH
break
}
current = current.next
}
}
}
// 删除一个微信小程序
function linkedNodeDelete(list, deleteItem) {
let current = list.head
let hasDeleteItem = true
// 删除的是链表第一个节点
if (list.head.id === deleteItem.id) {
list.head = list.head.next
list.length -= 1
} else {
while (current.next.id !== deleteItem.id) {
current = current.next
if (!current.next) {
// 说明没有在链表中找到该元素
hasDeleteItem = false
break
}
}
if (hasDeleteItem) {
let deleteNode = current.next
current.next = deleteNode.next
list.length -= 1
} else {
console.error('删除的元素不存在')
}
}
}
linkedListAppend(linkedList, wechatItem)
linkedListAppend(linkedList, jingDongItem)
linkedListAppend(linkedList, jueJinItem)
linkedListAppend(linkedList, meiTuanItem)
linkedListUse(linkedList, {
name: '简书',
id: 'f'
})
console.log('使用了简书', linkedList)
// linkedListUse(linkedList, jueJinItem)
// console.log('使用了掘金', linkedList)
// linkedNodeDelete(linkedList, jueJinItem)
// console.log('删除了掘金', linkedList)
数组版
// var arr = [{name: 'A'}, {name: 'B'}, [1,2,3]]
// var temp = arr[0]
// arr[0] = arr[2]
// arr[2] = temp
// console.log('arr', arr)
const MAX_DATA_LENGTH = 5
// 默认数据
var showData = [
{
name: '微信读书',
img: 'a.png',
id: 'a'
},
{
name: '京东到家',
img: 'b.png',
id: 'b'
},
{
name: '小妖营销',
img: 'c.png',
id: 'c'
},
{
name: '美团',
img: 'd.png',
id: 'd'
},
]
// 使用其中一个,把它变到第一个去, 使用的小程序为useItem
function useSmallProgram (useItem) {
let useIndex = showData.findIndex((item) => item.id === useItem.id)
if (useIndex === -1) {
showData.shift(useItem)
} else {
let temp = showData[useIndex]
showData[useIndex] = showData[0]
showData[0] = temp
}
if (showData.length > MAX_DATA_LENGTH) {
showData.length = MAX_DATA_LENGTH
}
console.log('showData', showData)
}
// 删除小程序
function deleteSmallProgram (deleteItem) {
let deleteIndex = showData.findIndex((item) => item.id === deleteItem.id)
showData.splice(deleteIndex, 1)
console.log('showData', showData)
}
useSmallProgram({
name: '美团',
img: 'd.png',
id: 'd'
})
// deleteSmallProgram({
// name: '小妖营销',
// img: 'c.png',
// id: 'c'
// })