列表节点类
class ListNode {
constructor(data) {
this.data = data
this.next = null
}
}
链接列表类
class LinkedList {
constructor(head = null) {
this.head = head
}
}
创建链接列表
let node1 = new ListNode(2)
let node2 = new ListNode(5)
node1.next = node2
let list = new LinkedList(node1)
console.log(list.head.next.data) //returns 5
size() {
let count = 0;
let node = this.head;
while (node) {
count++;
node = node.next
}
return count;
}
const ListFunctions = {
display: (linkedList) => {
items = [];
if (linkedList.head === null) {
return "The list is empty";
} else {
let currNode = linkedList.head;
while (currNode.next !== null) {
items.push(currNode.data);
currNode = currNode.next;
}
items.push(currNode.data);
}
return `Linked List Items: ${items.join("->")}`;
}
isEmpty: (linkedList) => {
if (linkedList.head === null) {
return `This list is empty`;
}
return `There are items in this list`;
}
find(item) {
let currNode = this.head;
if (!this.head) {
return null;
}
while (currNode.data !== item) {
if (currNode.next === null) {
return null;
} else {
currNode = currNode.next;
}
}
return currNode;
}
}
clear() {
this.head = null;
}
remove(item) {
if (!this.head) {
return null;
}
if (this.head.data === item) {
this.head = this.head.next;
return;
}
let currNode = this.head;
let previousNode = this.head;
while (currNode !== null && currNode.data !== item) {
previousNode = currNode;
currNode = currNode.next;
}
if (currNode === null) {
return;
}
previousNode.next = currNode.next;
}
insertFirst(item) {
this.head = new _Node(item, this.head);
}
insertLast(item) {
if (this.head === null) {
this.insertFirst(item);
} else {
let tempNode = this.head;
while (tempNode.next !== null) {
tempNode = tempNode.next;
}
tempNode.next = new _Node(item, null);
}
}
insertBefore(item, key) {
if (!this.head) {
return;
}
if (this.head.data === key) {
this.insertFirst(item);
return;
}
let currNode = this.head;
let previousNode = this.head;
while (currNode !== null && currNode.data !== key) {
previousNode = currNode;
currNode = currNode.next;
}
if (currNode === null) {
console.log(`key value not found`);
return;
}
previousNode.next = new _Node(item, currNode);
}
insertAfter(item, key) {
if (!this.head) {
return;
}
if (this.head.data === key) {
this.insertFirst(item);
return;
}
let currNode = this.head;
let nextNode = this.head;
while (currNode !== null && currNode.data !== key) {
currNode = nextNode;
nextNode = nextNode.next;
}
if (currNode === null) {
console.log(`key value not found`);
return;
}
currNode.next = new _Node(item, nextNode);
}
getLast() {
let lastNode = this.head;
if (lastNode) {
while (lastNode.next) {
lastNode = lastNode.next
}
}
return lastNode
}
getFirst() {
return this.head;
}
findPrevious: (linkedList, key) => {
if (linkedList.head === null) {
return null;
}
let prevNode;
let currNode = linkedList.head;
while (currNode.data !== key) {
prevNode = currNode;
currNode = currNode.next;
}
return `The previous node is ${prevNode.data}`;
}
在这些演习中,您将练习创建一个链接的列表,实施其核心和一些补充操作。您还将使用链接列表来解决面试问题。不要忘记评估这些练习中的每一个。通过说明1个或更多样本输入和输出来开始每个问题。
从头开始编写一个链接的列表类和这些核心功能(插入First,insertlast,remove,find)。
在您的链接列表类中实现以下功能。请注意,这些应该是免费功能,而不是链接列表类的方法,因此在链接列表类中实现它们。使用练习1中创建的列表测试每个功能。
分析以下功能(不在IDE中运行它)以确定要解决的问题。该算法的时间复杂性是多少?
function WhatDoesThisProgramDo(lst) {
let current = lst.head;
while (current !== null) {
let newNode = current;
while (newNode.next !== null) {
if (newNode.next.value === current.value) {
newNode.next = newNode.next.next;
}
else {
newNode = newNode.next;
}
}
current = current.next;
}
}
编写算法以扭转链接列表。算法的时间复杂性应为线性(O(n))。在此练习中,请注意,我们不要求您仅在反向中打印链接列表,也不会使用另一个链接列表以相反的顺序存储该值。您的程序应扭转给定单链接列表的方向。换句话说,所有指针都应向后指向。奖励:使用递归和迭代算法解决此问题。
编写一个算法以从链接列表的末尾找到第三元素。请注意,您可能很想在链接列表类中添加长度属性。长度属性不是链接列表的典型属性,因此不要对提供给您的链接列表类进行任何修改。
编写算法以找到链接列表的中间元素。请注意,您可能很想在链接列表类中添加长度属性。长度属性不是链接列表的典型属性,因此不要对提供给您的链接列表类进行任何修改。此外,使用size()函数找到链接列表的大小,然后将其除以一半,将找不到链接列表的正确中间。因此,不要使用这两种方法。
编写一种算法以查找链接列表是否具有周期(即,列表中的节点是否具有下一个值指向列表中的一个节点的下一个值)。对于此练习,创建一个名称Cyclelist的链接列表。请确保将节点插入列表中,以使其具有一个周期。然后使用Cyclelist功能测试您的程序。
实现双重链接列表。双链接列表的主要功能将是插入(首先,最后,之前,之后和at),删除并查找。编写一个函数aintll,并在其中创建双重链接的列表DLL,然后添加以下项目:Aquaria,caprica,gemenon,picon,picon,sagittaron。
给定上面的双重链接列表,编写一个逆转双重链接列表的程序。这种实现与逆转单链接列表有何不同?