前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >终于上线了,速来!

终于上线了,速来!

作者头像
labuladong
发布2024-01-08 10:36:24
1500
发布2024-01-08 10:36:24
举报

之前发布了算法可视化面板之后,有很多读者希望能够在可视化面板运行自己的代码。最近给我的算法学习网站自建了后端服务,可视化面板添加了编辑器功能,可以输入自定义代码了,可视化面板地址:

https://labuladong.online/algo-visualize

本文就简单介绍一下可视化编辑器的基本用法,更多功能尽请期待,欢迎大家体验和反馈问题。由于公众号的限制,无法在页面嵌入交互式教程,可以在电脑浏览器查看交互式教程。

编辑器交互式使用教程(本文):

https://labuladong.online/algo/intro/visualize-editor/

算法可视化实用技巧交互式教程:

https://labuladong.online/algo/intro/visualize/

运行自定义代码比较消耗计算资源,所以可视化服务对用户的行为限制较严格,正常使用不会出现问题,但不要用程序恶意请求后端 API,否则会被自动封号。如遇到误封的情况请留言。

只需微信扫码即可登录使用可视化面板,点击「编辑」按钮后可以输入并提交你的算法代码进行可视化:

目前只支持 JavaScript 语言,后续计划支持 Python 语言,但是现在 AI 这么厉害,改写一下语言应该的不算什么困难的,对吧。

编辑器如何使用呢?

简单说,像数组哈希表这种编程语言内置的数据结构,就按照正常编程的用法即可,对于力扣特有的比如 ListNode, TreeNode 之类的数据结构,用法和力扣保持一致

除了数据结构操作的可视化,还支持用 @visualize 标签 对递归算法进行可视化,大幅降低读者理解递归算法的难度

下面就简单介绍一下可视化面板编辑器的使用方法。

操作内置数据结构

类似数组、哈希表等 JavaScript 内置的数据结构,就正常初始化和操作它们即可,比如:

需要着重讲的是 力扣/LeetCode 中一些特殊的数据结构,比如单链表ListNode和二叉树TreeNode,它们的基本定义和用法和力扣上一样,下面提供一些例子。

操作单链表

首先说一下单链表,你可以用ListNode.create方法快速创建一条单链表,这是一个简单的例子:

代码语言:javascript
复制
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */

// 创建两条单链表
let head1 = ListNode.create([1, 4, 3, 2, 8]);
let head2 = ListNode.create([5, 6]);

// 遍历单链表
let arr = []
for (let p = head1; p !== null; p = p.next) {
  arr.push(p.val);
}

// 把第二条链表接到第一条链表的中间
head2.next.next = head1.next.next.next;

// 当然,你也可以手动组装链表
let node1 = new ListNode(1);
let node2 = new ListNode(2);
node1.val = 66
// node1 -> node2
node1.next = node2;
// node3 -> node1 -> node2
let node3 = new ListNode(3, node1);

单链表的每个节点有val, next属性,和力扣上的定义完全一致。

操作二叉树

再说一下二叉树,你可以用TreeNode.create方法快速创建一棵二叉树。注意我们用列表来表示二叉树,表示方式和 力扣题目中表示二叉树的方式 相同,这里举两个例子:

代码语言:javascript
复制
/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */

let root1 = TreeNode.create([3,9,20,null,null,15,7])
let node = root1.right.left;
let nodeVal = node.val;
node.val = 99;

// 当然,你也可以手动组装二叉树节点
let leftNode = new TreeNode(2);
let rightNode = new TreeNode(3);
let root2 = new TreeNode(1, null, rightNode);
root2.left = leftNode;

每个二叉树节点有val, left, right属性,和力扣上的定义完全一致。

操作多叉树

多叉树的节点定义和表示方法也和力扣完全一致,可以用Node.create来创建多叉树。

大家主要注意一下多叉树的表示方法,我们还是用列表来表示多叉树,使用层序遍历的顺序,并用null来分割每组子节点,具体可以参考这道力扣题目 429. N 叉树的层序遍历 的示例。

代码语言:javascript
复制
/**
 * // Definition for a Node.
 * function Node(val, children) {
 *    this.val = val;
 *    this.children = children;
 * };
 */

let root1 = Node.create([1,null,3,2,4,null,5,6])
let node = root1.children[0].children[1]
let nodeVal = node.val
node.val = 99

// 当然,你也可以手动组装多叉树节点
let children = [new Node(2), new Node(3), new Node(4)]
let root2 = new Node(1, children);

每个多叉树节点有val, children属性,和力扣上的定义完全一致。

可视化递归过程

我的可视化面板的一大特色,就是结合之前讲解的 学习数据结构和算法的框架思维,把递归过程可视化出来,帮助读者理解递归过程。具体的效果和使用技巧可以看 在网站/插件中使用可视化面板,我这里只说明如何在编辑器中开启递归过程的追踪。

核心就在于在你的递归函数上加上@visualize注释,比如这个斐波那契数列的例子:

代码语言:javascript
复制
// @visualize status(n)
var fib = function(n) {
    if (n < 2) {
        return n;
    }
    return fib(n - 1) + fib(n - 2);
}

let result = fib(5)

具体的含义是:

1、对这个fib函数开启递归树可视化功能,每次递归调用会被可视化为递归树上的一个节点,函数参数中的n的值会显示在节点上。

2、如果函数有返回值,那么当函数结束,计算出某个节点返回值时,鼠标移动到这个节点上,会显示该返回值。

3、fib函数被视为一个遍历这棵递归树的指针,处于堆栈路径的树枝会加粗显示。

使用 @visualize 的注意事项: 1、定义函数时,需要使用var fib = function(n) { ... }的方式,不要使用function fib(n) { ... }的方式,否则无法追踪递归过程。 2、@visualize注释必须写在函数定义的上一行,否则无法追踪递归过程。

再举个回溯算法的例子,根据 回溯算法核心框架,我们可以把track列表可视化出来观察回溯过程:

代码语言:javascript
复制
var permuteRepeat = function(nums) {
  let res = [];
  let track = [];

  backtrack(nums, track, res);
  return res;
}

// 把 track 的变化可视化到递归树上
// @visualize status(track)
var backtrack = function(nums, track, res) {
  // 触发结束条件
  if (track.length === nums.length) {
    res.push([...track]); // 将列表添加到result中
    return;
  }

  for (let i = 0; i < nums.length; i++) {
    // 做选择
    track.push(nums[i]);
    // 进入下一层决策树
    backtrack(nums, track, res);
    // 取消选择
    track.pop();
  }
}

let result = permuteRepeat([1, 2, 3]);

当然,根据 从二叉树彻底理解一切递归算法 所讲,回溯算法属于二叉树遍历的思路,backtrack函数没有返回值,所以鼠标移动道节点上也不会显示返回值。

最后

欢迎大家使用可视化面板/编辑器学习算法,如果遇到问题或者 bug,可以直接在本文下方留言。

可视化编辑器正在和我的 Chrome 配套插件VSCode 配套插件 以及 JetBrains 配套插件 整合。另外,我还做了一些实用有趣的小东西在内测,后续正式上线后再在公众号通知大家,敬请期待~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-01-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 labuladong 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 操作内置数据结构
  • 操作单链表
  • 操作二叉树
  • 操作多叉树
  • 可视化递归过程
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档