终于上线了,速来!

学算法认准 labuladong

点击卡片可搜索文章👇

68e8b15e5110713db2c45f6b9e28151f.png

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

https://labuladong.online/algo-visualize

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

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

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

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

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

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

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

2366d259b580a83ac15bdc7f4d91c7c2.jpeg

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

编辑器如何使用呢?

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

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

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

操作内置数据结构

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

7c58da8048a6779c09a6682ad1943b5f.png

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

操作单链表

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

/**
 * 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);

8f961f6e91bc2615fce7bdf8c09a0b26.jpeg

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

操作二叉树

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

/**
 * 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;

d355a16dca35b2fccccbc38dc3c272f8.jpeg

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

操作多叉树

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

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

/**
 * // 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);

d8884e74a20337db8f07e60820973d62.jpeg

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

可视化递归过程

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

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

// @visualize status(n)
var fib = function(n) {
    if (n < 2) {
        return n;
    }
    return fib(n - 1) + fib(n - 2);
}

let result = fib(5)

0b0229baaff04bf8b05291c75ac4c34d.jpeg

具体的含义是:

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

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

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

使用 @visualize 的注意事项:

1、定义函数时,需要使用var fib = function(n) { ... }的方式,不要使用function fib(n) { ... }的方式,否则无法追踪递归过程。

2、@visualize注释必须写在函数定义的上一行,否则无法追踪递归过程。

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

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]);

54ad858729687005197640a411de8b0e.jpeg

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

最后

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

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

  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值