最近刷算法题,经常有链表和二叉树的结构,在线运行代码都是直接传入链表或者二叉树的头节点,但是JS中没有这样的结构,本地没办法进行调试。今天专门写了下JS生成链表和二叉树的方法,下次本地调试就可以直接生成测试用例了。
链表生成
代码如下:
// ListNode构造器,用于创建链表的每个节点
class ListNode {
constructor(val, next) {
this.val = (val == undefined ? 0 : val);
this.next = (next == undefined ? null : next);
}
}
// 生成链表
function generateLinklist(arr) {
let head = new ListNode(arr[0]), // 初始化第一个节点作为头节点
curr = head; // curr指针保存当前节点
for(let i=1; i<arr.length; i++) {
curr.next = new ListNode(arr[i]); // 创建next节点
curr = curr.next; // curr后移一位
}
return head // 返回头节点
}
// 调用
const head = generateLinklist([1, 2, 3, 4]);
console.log(head); // 1 -> 2 -> 3 -> 4
实现思路还是比较简单的,但是有一个地方需要注意,curr
只能保存当前节点,即下一节点还没创建的时候不能提前移动。生成链表的方法本人最开始是这样写的:
// 注意,下面这段代码是错误的
function generateLinklist(arr) {
let obj = new Linklist(arr[0]),
curr = obj.next;
for(let i=1; i<arr.length; i++) {
curr = new Linklist(arr[i]);
curr = curr.next;
}
return obj
}
上面的代码咋一看好像也没问题,但是拿上面用例进行测试的时候发现返回的链表只有一个节点,后面都不见了:
ListNode { val: 1, next: null }
这段代码的问题就在于,curr
提前进行移动了。上面的代码中,先初始化第一个节点obj
作为头节点,然后curr = obj.next
的本意是希望curr
指向obj
的下一节点。但是curr
并没有指向“下一节点”,而是指向了null
,因为下一节点根本还没创建。因为obj.next == null
,所以curr = obj.next
相当于curr = null
,如下图所示:
这样一来,执行curr = new Linklist(arr[i]);
的时候,链表的第二个节点的指针其实是赋给了curr
,而不是obj.next
。
后面每一次for
循环,都是先将新的节点指针赋给curr
,然后执行curr = curr.next;
将curr
的值改为null
,而这些操作都与obj
无关,obj
还是最开始那个创建的头节点。
所以从这里得出一个结论,当下一节点还未创建的时候,指针不能提前移动。在第一段代码中,我们看到是先创建节点,再移动curr
指针的。
二叉树生成
层序遍历的反向操作,也是利用队列实现,代码如下:
// treeNode构造器
class treeNode {
constructor(val, left, right) {
this.val = (val == undefined ? 0 : val);
this.left = (left == undefined ? null : left);
this.right = (right == undefined ? null : right);
}
}
// 生成二叉树
function generateBinarySearchTree(arr) {
let root = new treeNode(arr[0]),
curr = root,
queue = new Array(),
n = 0;
queue.push(curr);
while(queue.length > 0) {
let size = queue.length;
for(let i=0; i<size; i++) {
curr = queue.pop();
curr.left = arr[n+1] ? new treeNode(arr[n+1]) : null;
curr.left && queue.unshift(curr.left); // 如果是null就不入队
n++;
curr.right = arr[n+1] ? new treeNode(arr[n+1]) : null;
curr.right && queue.unshift(curr.right); // 如果是null就不入队
n++;
}
}
return root
}
generateBinarySearchTree([1, 2, 3, 4, 5, 6, 7])
代码感觉有些地方可以优化,有空再改下。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。