JS数据结构第六篇 --- 二叉树力扣练习题

递归+迭代两种实现方式:
/** 反转二叉树
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {TreeNode}
* 第一种方式迭代
* 执行用时 :72 ms, 在所有 JavaScript 提交中击败了87.29%的用户
* 内存消耗 :33.8 M, 在所有 JavaScript 提交中击败了24.26%的用户
*/
var invertTree = function(root) {
if (!root) return root; var arr = [root]; while(arr.length){
var current = arr.shift(); //取出节点,交换左右子节点
var temp = current.right;
current.right = current.left;
current.left = temp; //将左右子节点push到数组中
if (current.right) arr.push(current.right);
if (current.left) arr.push(current.left);
}
return root;
}; /**
* 第二种方式递归
* @param root
* @returns {*}
* 执行用时 :64 ms, 在所有 JavaScript 提交中击败了98.02%的用户
* 内存消耗 :33.6 MB, 在所有 JavaScript 提交中击败了53.85%的用户
*/
var invertTree2 = function(root) {
if (!root) return root; var temp = invertTree(root.left);
root.left = invertTree(root.right);
root.right = temp;
return root;
};

初看这个题目描述,没怎么看懂,特别是控制台的输入输出
比如输入:[3, 9, 20, 15, 7, 88, 16, 2, 19, 13, 26, 11]
输出是:[3,9,15,2,19,7,13,26,20,88,11,16]
一时没弄明白,后面琢磨了一下,才发现力扣这里的输入是按照输入顺序来组成树的,而不是按输入的大小组成树。
即上面这个输入的数字列表,做成二叉树图为:

如果输入的数字列表中带有null, 则null所在的子树空不占位,
比如输入:[3, 9, null, 20, 15, 7, 88, 16, 2, 19, null, 13, 26, 11]
输出为:[3, 9, 20, 7, 19, 88, 13, 26, 15, 16, 11, 2]
输入数字的二叉树图为:

理解了力扣题目的输入输出逻辑,咱们再做题,二叉树的前序遍历递归+迭代方式code (先根节点,再左子节点,再右子节点):
/** 前序遍历规则:先根节点,再左子节点,再右子节点
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/** 第一种方式:递归
* @param {TreeNode} root
* @return {number[]}
执行用时 :72 ms, 在所有 JavaScript 提交中击败了86.38%的用户
内存消耗 :33.8 MB, 在所有 JavaScript 提交中击败了17.62%的用户
*/
var preorderTraversal = function(root) {
var arr = [];
recusion(root, arr);
return arr; function recusion(root){
if (!root) return;
//前序遍历,先根节点,再左节点,再右节点
arr.push(root.val);
recusion(root.left, arr);
recusion(root.right, arr);
}
}; // function TreeNode(val) {
// this.val = val;
// this.left = this.right = null;
// } /**
* 第二种方式:迭代
* 执行用时 :76 ms, 在所有 JavaScript 提交中击败70.96%的用户
* 内存消耗 :33.6 MB, 在所有 JavaScript 提交中击败了60.62%的用户
*/
var preorderForeach = function(root) {
var res = [];
if (!root) return res;
var arr = [root];
while(arr.length){
//借助于栈的特性:后进先出
var current = arr.pop();
res.push(current.val); //先将右节点压入栈底,因为右节点后取值
if (current.right){
arr.push(current.right);
}
//左节点先取值,压入栈顶
if (current.left){
arr.push(current.left);
}
}
return res;
};

二叉树中序遍历,先找到最左边的左子节点,从这里开始,然后左子节点, 再根节点,再右子节点:
/** 中序遍历:从小到大,从做左边的左子节点,最后一个是右边的右子节点
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/** 中序遍历:按照从小到大排序,先找到最左边的子节点,也就是最小值,再依次往上走父节点,右节点
* @param {TreeNode} root
* @return {number[]}
* 第一种方式:递归
* 执行用时 :64 ms, 在所有 JavaScript 提交中击败了97.67%的用户
* 内存消耗 :33.8 MB, 在所有 JavaScript 提交中击败20.52%的用户
*/
var inorderTraversal = function(root) {
const res = [];
if (!root) return res;
recusion(root);
return res; function recusion(root){
if (!root) return; recusion(root.left);
res.push(root.val);
recusion(root.right);
}
}; /**
* 第二种方式:迭代
* 执行用时 :68 ms, 在所有 JavaScript 提交中击败了94.67%的用户
* 内存消耗 33.7 MB, 在所有 JavaScript 提交中击败了30.60%的用户
*/
var inorderTraversal2 = function(root) {
const res = [];
if (!root) return res; const arr = [];
while (root || arr.length){
while(root){
arr.push(root);
root = root.left;
}
root = arr.pop(); //最后一个左节点
res.push(root.val);
root = root.right;
}
return res;
};
4、第145题:二叉树的后序遍历

后序遍历的规则:先叶子节点,再根节点;即先左子节点,再右子节点,再根节点。
/** 后序遍历规则:先叶子节点,叶子节点先左后右,再根节点
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/** 后序遍历:先叶子节点,再左子树,再右子树
* 第一种方式:递归
* @param {TreeNode} root
* @return {number[]}
* 执行用时 :76 ms, 在所有 JavaScript 提交中击败了68.85%的用户
* 内存消耗 :33.9 MB, 在所有 JavaScript 提交中击败了9.84%的用户
*/
var postorderTraversal = function(root) {
var res = [];
if (!root) return res;
recusion(root);
return res; function recusion(root){
if (!root) return; recusion(root.left);
recusion(root.right);
res.push(root.val);
}
}; /**
* 第二种方式:迭代
* @param root
* @returns {Array}
* 执行用时 :80 ms, 在所有 JavaScript 提交中击败了48.15%的用户
* 内存消耗 :33.7 MB, 在所有 JavaScript 提交中击败25.41%的用户
*/
var postorderTraversal = function(root) {
var res = [];
if (!root) return res; var arr = [root];
while (arr.length){
var current = arr.pop();
res.unshift(current.val); if (current.left){
arr.push(current.left);
}
if (current.right){
arr.push(current.right);
}
}
return res;
};

递归层级遍历和前序遍历差不多,迭代方式层级遍历有点绕
/** 层次遍历
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
* 给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
] */
/** 层次遍历,第一种方式:递归, 和前序遍历差不多
* @param {TreeNode} root
* @return {number[][]}
* 执行用时 :84 ms, 在所有 JavaScript 提交中击败了55.19%的用户
* 内存消耗 :34.6 M, 在所有 JavaScript 提交中击败了53.23%的用户
*/
var levelOrder = function(root) {
var res = [];
if (!root) return res;
recusion(root, 0);
return res; function recusion(root, level){ if (!root) return; if (res[level]){
res[level].push(root.val);
}
else{
res[level] = [root.val];
} if (root.left){
recusion(root.left, level+1);
}
if (root.right){
recusion(root.right, level+1);
}
}
}; /**
* 第二种层序遍历:迭代
* @param root
* @returns {Array}
* 执行用时 :80 ms, 在所有 JavaScript 提交中击败了73.64%的用户
* 内存消耗 :34.8 MB, 在所有 JavaScript 提交中击败了28.36%的用户
*/
var levelOrder2 = function(root) {
var res = [];
if (!root) return res; var queue = [root];
while(queue.length){ //内循环把这一层级的所有节点都放入tempQueue队列中,每一个外循环则是每一层级重新开始
var arr = [], tempQueue = [];
while(queue.length){
var current = queue.shift();
arr.push(current.val); if (current.left){
tempQueue.push(current.left);
}
if (current.right){
tempQueue.push(current.right);
}
console.log("tempQueue.length: ", tempQueue.length, ", queue.length: ", queue.length);
console.log("-----------")
}
res.push(arr);
queue = tempQueue; console.log(JSON.stringify(res))
console.log("***************************")
}
return res;
}; // function TreeNode(val){
// this.val = val;
// this.left = this.right = null;
// }
//
// var node = new TreeNode(23);
// node.left = new TreeNode(16);
// node.right = new TreeNode(45);
// node.left.left = new TreeNode(3);
// node.left.right = new TreeNode(22);
// node.right = new TreeNode(45);
// node.right.left = new TreeNode(37);
// node.right.right = new TreeNode(99);
// console.log(levelOrder2(node));

二叉树的最大深度和求二叉树的层级遍历差不多
/** 二叉树的最大深度
* 给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number}
* 第一种方式:递归
* 执行用时 :96 ms, 在所有 JavaScript 提交中击败了51.18%的用户
* 内存消耗 :37.1 MB, 在所有 JavaScript 提交中击败了40.00%的用户
*/
var maxDepth = function(root) {
if (!root) return 0; var maxLevel = 1;
recusion(root, 1);
return maxLevel; function recusion(root, level){ if (level > maxLevel) {
maxLevel = level;
} if (root.left){
recusion(root.left, level+1);
}
if (root.right){
recusion(root.right, level+1);
}
}
}; /**
* 第二种:迭代
* @param root
* @returns {number}
执行用时 :88 ms, 在所有 JavaScript 提交中击败了81.91%的用户
内存消耗 :36.8 MB, 在所有 JavaScript 提交中击败了93.61%的用户
*/
var maxDepth2 = function(root) {
if (!root) return 0; var level = 0, queue = [root];
while(queue.length){
var tempQueue = [];
//内循环,每次把整个层级节点遍历完, tempQueue存储每个层级的所有节点
while(queue.length){
var current = queue.shift(); if (current.left){
tempQueue.push(current.left);
}
if (current.right){
tempQueue.push(current.right)
}
}
level++;
queue = tempQueue;
}
return level;
}; // function TreeNode(val){
// this.val = val;
// this.left = this.right = null;
// }
//
// var node = new TreeNode(3);
// node.left = new TreeNode(9);
// node.right = new TreeNode(20);
// node.right.left = new TreeNode(15);
// node.right.right = new TreeNode(7);
// console.log(maxDepth(node))


这个题和二叉树层级遍历/求最大深度类似,但比层级遍历要绕要麻烦点。
迭代方式:迭代遍历,用2个栈,一个用来存储每一层级的节点,另一个栈用来存储每个节点的编号。
对节点进行编号,规则:根节点编号从0开始,左子节点编号 = 父节点编号 * 2 + 1, 右子节点编号 = 父节点编号 * 2 + 2;
递归方式:规则同迭代方式,也是对节点进行编号
如图:
/**
* 给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空。
每一层的宽度被定义为两个端点(该层最左和最右的非空节点,两端点间的null节点也计入长度)之间的长度。 示例 1:
输入:
1
/ \
3 2
/ \ \
5 3 9
输出: 4
解释: 最大值出现在树的第 3 层,宽度为 4 (5,3,null,9)。 示例 2:
输入:
1
/
3
/ \
5 3
输出: 2
解释: 最大值出现在树的第 3 层,宽度为 2 (5,3)。 示例 3:
输入:
1
/ \
3 2
/
5
输出: 2
解释: 最大值出现在树的第 2 层,宽度为 2 (3,2)。 示例 4:
输入:
1
/ \
3 2
/ \
5 9
/ \
6 7
输出: 8
解释: 最大值出现在树的第 4 层,宽度为 8 (6,null,null,null,null,null,null,7)。 * Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number}
* 第一种方式:递归
* 执行用时 :84 ms, 在所有 JavaScript 提交中击败了100.00%的用户
* 内存消耗 :36.7 MB, 在所有 JavaScript 提交中击败了37.50%的用户
*/
var widthOfBinaryTree = function(root) { if (!root) return 0; //queue存储节点,numArr存储节点对应的节点编号位置
var queue = [root], numArr = [0], maxWidth = 1; while (queue.length) {
//tempQueue存储每一层级所有的节点,tempNumArr存储对应节点的编号位置
var tempQueue = [], tempNumArr = [];
while (queue.length) {
var node = queue.shift(), num = numArr.shift(); //取出栈底节点和编号 if (node.left) {
tempQueue.push(node.left);
tempNumArr.push(num * 2 + 1);
}
if (node.right) {
tempQueue.push(node.right);
tempNumArr.push(num * 2 + 2);
}
}
var tempWidth = 0;
//计算tempNumArr中存储的这一层的宽度, 最后一位元素存储这一层级最大宽度的编号
if (tempNumArr.length) {
tempWidth = tempNumArr[tempNumArr.length - 1] - tempNumArr[0] + 1;
}
if (tempWidth > maxWidth) {
maxWidth = tempWidth; //更新最大宽度
} //开始下一个层级的宽度计算
queue = tempQueue;
numArr = tempNumArr;
} return maxWidth;
}; /**
* 第二种递归方式:
* @param root
* @returns {number}
* 执行用时 :84 ms, 在所有 JavaScript 提交中击败了100.00%的用户
* 内存消耗 :36 MB, 在所有 JavaScript 提交中击败了75.00%的用户
*/
var widthOfBinaryTree2 = function(root) { if (!root) return 0; var res = [], maxWidth = 1;
recusion(root, 0, 0);
return maxWidth; function recusion(root, level, num){ if (res[level]){
res[level].push(num);
}
else{
res[level] = [num];
} //计算最大宽度
var tempArr = res[level];
var tempWidth = tempArr[tempArr.length - 1] - tempArr[0] + 1;
if (tempWidth > maxWidth) {
maxWidth = tempWidth;
} if (root.left){
recusion(root.left, level + 1, num * 2 + 1);
}
if (root.right){
recusion(root.right, level + 1, num * 2 + 2);
}
}
}; // function TreeNode(val){
// this.val = val;
// this.left = this.right = null;
// }
//
// //[1,1,1,1,null,null,1,1,null,null,1]
// var root = new TreeNode(1);
// root.left = new TreeNode(1);
// root.right = new TreeNode(1);
// root.left.left = new TreeNode(1);
// root.left.right = new TreeNode(3);
// root.right.right = new TreeNode(9);
// console.log(widthOfBinaryTree(root));

N叉树和二叉树差不多,因此它的前序遍历也是在二叉树的前序遍历的基础上进行修改,递归+迭代:
/** N叉树的前序遍历
* // Definition for a Node.
* function Node(val,children) {
* this.val = val;
* this.children = children;
* };
*/
/**
* @param {Node} root
* @return {number[]}
* 第一种方式:递归
* 执行用时 :968 ms, 在所有 JavaScript 提交中击败了62.09%的用户
* 内存消耗 :81.5 MB, 在所有 JavaScript 提交中击败了29.48%的用户
*/
var preorder = function(root) {
if (!root) return []; var res = [];
recusion(root);
return res; function recusion(root){
if (!root) return; res.push(root.val);
for (var i = 0; i < root.children.length; i++){
recusion(root.children[i]);
}
}
}; /**
* 第二种方式:迭代
* @param root
* @returns {Array}
* 执行用时 :948 ms, 在所有 JavaScript 提交中击败了73.46%的用户
* 内存消耗 :87.4 MB, 在所有 JavaScript 提交中击败了6.32%的用户
*/
var preorder2 = function(root) {
if (!root) return []; var res = [], arr = [root];
while(arr.length){
var current = arr.pop();
res.push(current.val); for(var i = current.children.length - 1; i >= 0; i--){
arr.push(current.children[i]);
}
}
return res;
};

/**
* // Definition for a Node.
* function Node(val,children) {
* this.val = val;
* this.children = children;
* };
*/
/**
* @param {Node} root
* @return {number[]}
* 第一种方式:递归
* 执行用时 :964 ms, 在所有 JavaScript 提交中击败了54.40%的用户
* 内存消耗 :87.6 MB, 在所有 JavaScript 提交中击败了6.10%的用户
*/
var postorder = function(root) {
if (!root) return []; var res = [];
recusion(root);
return res; function recusion(root){
if (!root) return; for (var i = 0; i < root.children.length; i++){
recusion(root.children[i]);
}
res.push(root.val)
}
}; /**
* 第二种方式:迭代
* @param root
* @returns {Array}
* 执行用时 :904 ms, 在所有 JavaScript 提交中击败了93.41%的用户
* 内存消耗 :87.4 MB, 在所有 JavaScript 提交中击败了6.10%的用户
*/
var postorder2 = function(root) {
if (!root) return []; var res = [], arr = [root];
while(arr.length){
var current = arr.pop();
for(var i = 0; i < current.children.length; i++){
arr.push(current.children[i]);
}
res.unshift(current.val);
}
return res;
};

/**
* // Definition for a Node.
* function Node(val,children) {
* this.val = val;
* this.children = children;
* };
*/
/**
* @param {Node} root
* @return {number}
* 第一种方式:递归
* 执行用时 :1064 ms, 在所有 JavaScript 提交中击败了22.35%的用户
* 内存消耗 :83 MB, 在所有 JavaScript 提交中击败了50.68%的用户
*/
var maxDepth = function(root) {
if (!root) return 0; var maxLevel = 1;
recusion(root, 1);
return maxLevel; function recusion(root, level){ if (!root) return; if (level > maxLevel) {
maxLevel = level;
} for (var i = 0; i < root.children.length; i++){
recusion(root.children[i], level + 1);
}
}
}; /**
* 第二种方式:迭代
* @param root
* @returns {number}
执行用时 :908 ms, 在所有 JavaScript 提交中击败了81.01%的用户
内存消耗 :81.1 MB, 在所有 JavaScript 提交中击败了54.79%的用户
*/
var maxDepth2 = function(root) {
if (!root) return 0; var level = 0, queue = [root];
while(queue.length){
var tempQueue = [];
//内循环,每次把整个层级节点遍历完, tempQueue存储每个层级的所有节点
while(queue.length){
var current = queue.pop(); for (var i = 0; i < current.children.length; i++){
var node = current.children[i];
if (node){
tempQueue.push(node);
}
}
}
level++;
queue = tempQueue;
}
return level;
};

根据题意和示例,相当于是进行一次前序遍历,然后不保留左子树,全部移到右子树来。
/**
* 给定一个二叉树,原地将它展开为链表。
例如,给定二叉树 1
/ \
2 5
/ \ \
3 4 6
将其展开为: 1
\
2
\
3
\
4
\
5
\
6 根据提意,在原地展开为链表,相当于把左子树设为nul, 通过前序遍历全部转成右子树
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {void} Do not return anything, modify root in-place instead.
* 第一种方式:递归
* 执行用时 :92 ms, 在所有 JavaScript 提交中击败了55.97%的用户
* 内存消耗 :35.5 MB, 在所有 JavaScript 提交中击败了10.53%的用户
*/
var flatten = function(root) {
if (!root) return root; var preNode = root;
recusion(root);
return root; function recusion(node){ var leftNode = node.left, rightNode = node.right;
node.left = null; if (node != root){
preNode.right = node;
}
preNode = node; if (leftNode){
recusion(leftNode);
}
if (rightNode){
recusion(rightNode);
}
}
}; /**
* 第二种方式:迭代
* @param root
* @returns {*}
* 执行用时 :88 ms, 在所有 JavaScript 提交中击败了69.40%的用户
* 内存消耗 :34.7 MB, 在所有 JavaScript 提交中击败了52.63%的用户
*/
var flatten2 = function(root) {
if (!root) return root; var arr = [root], preNode = root;
while(arr.length){
var node = arr.pop(); if (node.right){
arr.push(node.right);
}
if (node.left){
arr.push(node.left);
} if (node != root){
preNode.right = node;
}
node.left = null;
preNode = node;
}
return root;
};

/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {number[]} preorder
* @param {number[]} inorder
* @return {TreeNode}
* 第一种方式:递归
* 执行用时 :104 ms, 在所有 JavaScript 提交中击败了91.63%的用户
* 内存消耗 :36.2 MB, 在所有 JavaScript 提交中击败了83.05%的用户
*/
var buildTree = function(preorder, inorder) {
return recusion(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); function recusion(preorder, preL, preR, inorder, inL, inR){
if (preL > preR || inL > inR){
return null;
} var rootVal = preorder[preL];
var temp = inL;
while (temp <= inR && inorder[temp] != rootVal){
temp++;
}
var root = new TreeNode(rootVal);
root.left = recusion(preorder, preL + 1, preL + temp - inL, inorder, inL, temp - 1);
root.right = recusion(preorder, preL + 1 - inL + temp, preR, inorder, temp + 1, inR); return root;
}
}; function TreeNode(val){
this.val = val;
this.left = this.right = null;
}
JS数据结构第六篇 --- 二叉树力扣练习题的更多相关文章
- JS数据结构第五篇 --- 二叉树和二叉查找树
一.二叉树的基本概念 从逻辑结构角度来看,前面说的链表.栈.队列都是线性结构:而今天要了解的“二叉树”属于树形结构. 1.1 多叉树的基本概念,以上图中“多叉树”为例说明 节点:多叉树中的每一个点都叫 ...
- JS数据结构第四篇 --- 栈
一.什么是数据结构栈 在数据结构中有一个栈结构,在内存空间中也有一个栈空间,这两个”栈“是两个不同的概念.这篇我们说的是数据结构中的栈.栈是一种特殊的线性表,特殊性在哪?就是只能在栈顶进行操作,往栈顶 ...
- JS数据结构第三篇---双向链表和循环链表之约瑟夫问题
一.双向链表 在上文<JS数据结构第二篇---链表>中描述的是单向链表.单向链表是指每个节点都存有指向下一个节点的地址,双向链表则是在单向链表的基础上,给每个节点增加一个指向上一个节点的地 ...
- JS原生第六篇 (帅哥)
复习 按钮不可用 disabled = "disabled" || true setTimeout 只执行一次 setInterval 执行很多次 递归调用 ...
- JS数据结构第二篇---链表
一.什么是链表 链表是一种链式存储的线性表,是由一组节点组成的集合,每一个节点都存储了下一个节点的地址:指向另一个节点的引用叫链:和数组中的元素内存地址是连续的相比,链表中的所有元素的内存地址不一定是 ...
- JS数据结构与算法 - 剑指offer二叉树算法题汇总
❗❗ 必看经验 在博主刷题期间,基本上是碰到一道二叉树就不会碰到一道就不会,有时候一个下午都在搞一道题,看别人解题思路就算能看懂,自己写就呵呵了.一气之下不刷了,改而先去把二叉树的基础算法给搞搞懂,然 ...
- 【HANA系列】【第六篇】SAP HANA XS使用JavaScript(JS)调用存储过程(Procedures)
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列][第六篇]SAP HANA XS ...
- 刷题-力扣-107. 二叉树的层序遍历 II
107. 二叉树的层序遍历 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/binary-tree-level-order-tr ...
- 解剖SQLSERVER 第十六篇 OrcaMDF RawDatabase --MDF文件的瑞士军刀(译)
解剖SQLSERVER 第十六篇 OrcaMDF RawDatabase --MDF文件的瑞士军刀(译) http://improve.dk/orcamdf-rawdatabase-a-swiss-a ...
随机推荐
- 15分钟让你了解如何实现并发中的Barrier
说到Barrier,很多语言中已经是标准库中自带的概念,一般情况下,只需要直接使用就行了.而最近一些机缘巧合的机会,我需要在c++中使用这么个玩意儿.但是c++标准库里还没有这个概念,只有boost里 ...
- 十分钟带你看一遍ES6新特性
let , const关键字 var 看习惯了java, 看js真的是忍不住想笑,比如说这个var,它太自由了,自由到{}根本限制不住它的生命周期 js的var关键字,无论在何处声明,都会被视为声明在 ...
- 编码规范 | Java函数优雅之道(上)
导读 随着软件项目代码的日积月累,系统维护成本变得越来越高,是所有软件团队面临的共同问题.持续地优化代码,提高代码的质量,是提升系统生命力的有效手段之一.软件系统思维有句话“Less coding, ...
- .net core使用MQTT
废话不多说,我们来直接实践…… 一.搭建mqtt控制台服务端 新建一个.net core控制台项目,然后使用Nuget添加MQTTnet包,我这里使用2.4版本,注意不同版本,代码写法不相同,如下图 ...
- java学习-NIO(二)Buffer
当我们需要与 NIO Channel 进行交互时, 我们就需要使用到 NIO Buffer, 即数据从 Buffer读取到 Channel 中, 并且从 Channel 中写入到 Buffer 中.缓 ...
- [转] java开源游戏
收藏一下 triplea Triplea是一个开放源码的boardgame.它允许玩家选择各种各样的战略版图游戏(如:轴心国或同盟军).TripleA引擎支持联网对战,支持声音,支持使用XML文 ...
- 图片格式:gif / png / pg / webp 介绍
本文引自:https://www.cnblogs.com/changyangzhe/articles/5718285.html GIF介绍 GIF 意为Graphics Interchange for ...
- 百度Echarts,蚂蚁金服G2,D3三种主流可视化工具对比
1.百度的Echarts 官网:https://echarts.baidu.com/ 介绍:ECharts,缩写来自Enterprise Charts,是百度推出的一款开源的,商业级数据图表,它最初是 ...
- Linux 目录递归赋权,解决 Linux权限不够
如你要操作一个目录下的文件时,系统提示 “权限不够”,可用以下方法解决. 如 test 文件目录. 1.用root账号登陆系统. 2.输入如下命令: chmod 777 test -R 这样访问.修改 ...
- Kafka之Producer
通过https://www.cnblogs.com/tree1123/p/11243668.html 已经对consumer有了一定的了解.producer比consumer要简单一些. 一.旧版本p ...