那些前端用js手搓出来的算法与数据结构链表篇
Posted 我是真的不会前端
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了那些前端用js手搓出来的算法与数据结构链表篇相关的知识,希望对你有一定的参考价值。
首先,一句话,前端学算法有啥用
低情商:好跟后端battle。顺便互相吹吹牛
高情商:提高业务能力。提炼基本功
实际:大厂大公司面试要问,没办法。
工作中:应用场景不多,基本都是后端玩的
那到底学不学
要不要高薪嘛,要你就最好学学,力扣刷刷题。说那么多干啥
那有哪些比较值得刷的算法呢
这里我整理了一些
包括很多其实在高校就会讲的线性表链表二叉树的算法,甚至还有很多别的算法,例如动态规划,贪心算法等等。这些算法往往伴随着面试官考察你的逻辑能力和你的知识深度。
如何用js写算法
(一)链表类
链式结构的创建
1.js没有指针 怎么操作地址,怎么创建链式结构
其实不用想太复杂了,既然js 尤其是现在的ts越来越像java,那这些就不会太复杂
一般链表长这样
一个节点有两条信息
指向链表中下一项的指针或引用(对于单链表)
节点的值
对于我们的节点,我们只需要创建一个函数,该函数接受一个值,并返回一个具有上面两个信息的对象:指向下一个节点的指针和该节点的值。
节点链表将包含五个方法:
push(value): 将值添加到链表的末尾
pop() 弹出链表中的最后一个值
get(index):返回给定索引中的项
delete(index):从给定索引中删除项
isEmpty(): 返回一个布尔值,指示链表是否为空
printList():不是链表的原生方法,它将打印出我们的链表,主要用于调试
构造函数方法:
class Node
constructor(data)
this.data = data; // 节点的数据域
this.prev = null; // 节点的指针域
this.next = null; // 节点的指针域
只要实现上述的这些方法,一个基本的单链表结构就实现了。
class SingleList
constructor()
this.size = 0; // 单链表的长度
this.head = new Node('head'); // 表头节点
this.currNode = ''; // 当前节点的指向
find(item) // 在单链表中寻找item元素
insert(item, element) // 向单链表中插入元素
remove(item) // 在单链表中删除一个节点
append(element) // 在单链表的尾部添加元素
findLast() // 获取单链表的最后一个节点
isEmpty() // 判断单链表是否为空
show() // 显示当前节点
getLength() // 获取单链表的长度
advance(n, currNode) // 从当前节点向前移动n个位置
display() // 单链表的遍历显示
clear() // 清空单链表
前端中常见常考算法
链表类
前序遍历判断回文链表
利用链表的后续遍历,使用函数调用栈作为后序遍历栈,来判断是否回文
let isPalinDrome = function(head)
let left = head;
function traverse(right)
if (right == null) return true;
let res = traverse(right.next);
res = res && (right.val === left.val);
left = left.next;
return res;
return traverse(head);
通过 快、慢指针找链表中点,然后反转链表,比较两个链表两侧是否相等,来判断是否是回文链表
同时回文链表是很多大厂特别喜欢考的算法题
var isPalindrome = function(head)
// 反转 slower 链表
let right = reverse(findCenter(head));
let left = head;
// 开始比较
while (right != null)
if (left.val !== right.val)
return false;
left = left.next;
right = right.next;
return true;
function findCenter(head)
let slower = head, faster = head;2. 反转链表
3. 合并K个升序链表
while (faster && faster.next != null)
slower = slower.next;
faster = faster.next.next;
// 如果 faster 不等于 null,说明是奇数个,slower 再移动一格
if (faster != null)
slower = slower.next;
return slower;
function reverse(head)
let prev = null, cur = head, nxt = head;
while (cur != null)
nxt = cur.next;
cur.next = prev;
prev = cur;
cur = nxt;
return prev;
2. 反转链表
* function ListNode(val)
* this.val = val;
* this.next = null;
*
* @param ListNode head
* @return ListNode
var reverseList = function(head)
if (head == null || head.next == null) return head;
let last = reverseList(head.next);
head.next.next = head;
head.next = null;
return last;
;
3. 合并K个升序链表
var mergeKLists = function(lists)
if (lists.length === 0) return null;
return mergeArr(lists);
;
function mergeArr(lists)
if (lists.length <= 1) return lists[0];
let index = Math.floor(lists.length / 2);
const left = mergeArr(lists.slice(0, index))
const right = mergeArr(lists.slice(index));
return merge(left, right);
function merge(l1, l2)
if (l1 == null && l2 == null) return null;
if (l1 != null && l2 == null) return l1;
if (l1 == null && l2 != null) return l2;
let newHead = null, head = null;
while (l1 != null && l2 != null)
if (l1.val < l2.val)
if (!head)
newHead = l1;
head = l1;
else
newHead.next = l1;
newHead = newHead.next;
l1 = l1.next;
else
if (!head)
newHead = l2;
head = l2;
else
newHead.next = l2;
newHead = newHead.next;
l2 = l2.next;
newHead.next = l1 ? l1 : l2;
return head;
K 个一组翻转链表
var reverseKGroup = function(head, k)
let a = head, b = head;
for (let i = 0; i < k; i++)
if (b == null) return head;
b = b.next;
const newHead = reverse(a, b);
a.next = reverseKGroup(b, k);
return newHead;
;
function reverse(a, b)
let prev = null, cur = a, nxt = a;
while (cur != b)
nxt = cur.next;
cur.next = prev;
prev = cur;
cur = nxt;
return prev;
5. 环形链表
var hasCycle = function(head)
if (head == null || head.next == null) return false;
let slower = head, faster = head;
while (faster != null && faster.next != null)
slower = slower.next;
faster = faster.next.next;
if (slower === faster) return true;
return false;
6. 排序链表(带头结点)
/**
* Definition for singly-linked list.
* function ListNode(val)
* this.val = val;
* this.next = null;
*
*/
/**
* @param ListNode head
* @return ListNode
*/
var sortList = function(head)
if (head == null) return null;
let newHead = head;
return mergeSort(head);
;
function mergeSort(head)
if (head.next != null)
let slower = getCenter(head);
let nxt = slower.next;
slower.next = null;
console.log(head, slower, nxt);
const left = mergeSort(head);
const right = mergeSort(nxt);
head = merge(left, right);
return head;
function merge(left, right)
let newHead = null, head = null;
while (left != null && right != null)
if (left.val < right.val)
if (!head)
newHead = left;
head = left;
else
newHead.next = left;
newHead = newHead.next;
left = left.next;
else
if (!head)
newHead = right;
head = right;
else
newHead.next = right;
newHead = newHead.next;
right = right.next;
newHead.next = left ? left : right;
return head;
function getCenter(head)
let slower = head, faster = head.next;
while (faster != null && faster.next != null)
slower = slower.next;
faster = faster.next.next;
return slower;
7. 相交链表(也称十字链表)
Definition for singly-linked list.
function ListNode(val)
this.val = val;
this.next = null;
@param ListNode headA
@param ListNode headB
@return ListNode
var getIntersectionNode = function(headA, headB)
let lastHeadA = null;
let lastHeadB = null;
let originHeadA = headA;
let originHeadB = headB;
if (!headA || !headB)
return null;
while (true)
if (headB == headA)
return headB;
if (headA && headA.next == null)
lastHeadA = headA;
headA = originHeadB;
else
headA = headA.next;
if (headB && headB.next == null)
lastHeadB = headB
headB = originHeadA;
else
headB = headB.next;
if (lastHeadA && lastHeadB && lastHeadA != lastHeadB)
return null;
return null;
以上是关于那些前端用js手搓出来的算法与数据结构链表篇的主要内容,如果未能解决你的问题,请参考以下文章