树的测试框架:

 // leetcodeTree.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <iostream>
#include <queue>
#include <stack>
#include <vector> using namespace std; struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) { };
};
struct TreeLinkNode {
int val;
TreeLinkNode *left;
TreeLinkNode *right;
TreeLinkNode *next;
TreeLinkNode(int x) : val(x) { left = nullptr; right = nullptr; next = nullptr; };
}; TreeNode* build(TreeNode *root, int val) { // 构造一棵树
if (root == nullptr) {
root = new TreeNode(val);
return root;
}
if (val < root->val)
root->left = build(root->left, val);
else
root->right = build(root->right, val); return root;
} vector<int> preOrderTraversal(TreeNode *root) { // 非递归先序遍历
vector<int> result;
stack<TreeNode*> stk;
if (root != nullptr)
stk.push(root);
while (!stk.empty()) {
TreeNode *p = stk.top();
stk.pop();
cout << '\t' << p->val; // 打印遍历序列
result.push_back(p->val); if (p->right != nullptr) // 注意是先进栈右孩子,再进栈左孩子
stk.push(p->right);
if (p->left != nullptr)
stk.push(p->left);
}
return result;
} int main() {
int t[] = {,,,,};
TreeNode* root = nullptr;
for(int i=;i<sizeof(t)/sizeof(int);++i) // build a tree
build(root,t[i]); preOrderTraversal(root); return ;
}

测试框架

1,Binary Tree Preorder Traversal(非递归)

 vector<int> preOrderTraversal(TreeNode *root) {  // 非递归先序遍历
vector<int> result;
stack<TreeNode*> stk;
if (root != nullptr)
stk.push(root);
while (!stk.empty()) {
TreeNode *p = stk.top();
stk.pop();
cout << '\t' << p->val;
result.push_back(p->val); if (p->right != nullptr) // 注意是先进栈右孩子,再进栈左孩子
stk.push(p->right);
if (p->left != nullptr)
stk.push(p->left);
}
return result;
}

preOrderTraversal

2,Binary Tree Inorder Traversal(非递归)

 vector<int> inOrderTraversal(TreeNode *root) {  // 非递归中序遍历
vector<int> result;
stack<TreeNode*> stk;
TreeNode *p = root; while (!stk.empty() || p != nullptr) {
if (p != nullptr) {
stk.push(p);
p = p->left;
}
else {
p = stk.top();
stk.pop();
cout << '\t' << p->val;
result.push_back(p->val);
p = p->right;
}
}
return result;
}

inOrderTraversal

3,Binary Tree Postorder Traversal(非递归)

 vector<int> postOrderTravelsal(TreeNode *root) {
vector<int> result;
stack<TreeNode*> stk;
if (root == nullptr)
return result; TreeNode *pCur, *pLastVisit;
pCur = root;
pLastVisit = nullptr; while (pCur) { // 把 pCur 移动到最左下方
stk.push(pCur);
pCur = pCur->left;
}
while (!stk.empty()) {
pCur = stk.top();
stk.pop();
if (pCur->right == nullptr || pCur->right == pLastVisit) { // 如果当前节点无右子树或者右子树已经被访问过,则访问
result.push_back(pCur->val);
cout << '\t' << pCur->val;
pLastVisit = pCur;
}
else { // 跳到右子树去
stk.push(pCur); // 根节点再次入栈
pCur = pCur->right;
while (pCur) {
stk.push(pCur);
pCur = pCur->left;
}
}
}
cout << endl;
return result;
}

postOrderTravelsal

4,Binary Tree Level Order Traversal(不区分层)

 void levelOrderI(TreeNode* root) {  // 层次遍历,不分层次
if (root == nullptr)
return;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
TreeNode *temp = q.front();
q.pop();
cout << temp->val << '\t';
if (temp->left)
q.push(temp->left);
if (temp->right)
q.push(temp->right);
}
cout << endl;
}

levelOrder

5,Binary Tree Level Order Traversal(区分层次)

 vector<vector<int>> levelOrderII1(TreeNode* root) { // 迭代版
vector<vector<int>> result;
queue<TreeNode*> current, next; if (root == nullptr)
return result;
else
current.push(root); while (!current.empty()) {
vector<int> level; // elements in one level
while (!current.empty()) {
TreeNode *node = current.front();
current.pop();
level.push_back(node->val);
if (node->left)
next.push(node->left);
if (node->right)
next.push(node->right);
}
result.push_back(level);
swap(current, next);
}
return result;
} void traverse(TreeNode *root, size_t level, vector<vector<int>>& result) {
if (!root)
return;
if (level > result.size())
result.push_back(vector<int>()); // 如果层数不够,新加一层来存储 result[level - ].push_back(root->val);
traverse(root->left, level + , result);
traverse(root->right, level + , result);
}
vector<vector<int>> levelOrderII2(TreeNode* root) { // 递归版
vector<vector<int>> result;
traverse(root, , result);
return result;
}

levelOrder(分层)

6,Binary Tree Level Order Traversal(分层,从下向上)

 vector<vector<int>> levelOrderBottomI(TreeNode *root) {  // 递归版
vector<vector<int>> result;
traverse(root, , result);
reverse(result.begin(), result.end()); // 多了这一行,调用相同的函数
return result;
} vector<vector<int>> levelOrderBottomII(TreeNode *root) {
vector<vector<int>> result;
if (root == nullptr)
return result; queue<TreeNode*> current, next; current.push(root);
while (!current.empty()) {
vector<int> level; // elments in one level
while (!current.empty()) {
TreeNode *node = current.front();
current.pop();
level.push_back(node->val);
if (node->left)
next.push(node->left);
if (node->right)
next.push(node->right);
}
result.push_back(level);
swap(next, current);
}
reverse(result.begin(), result.end()); // 多了这一行
return result;
}

levelOrderBottom

7,Binary Tree Zigzag Level Order Traversal

 void traverse(TreeNode *root, size_t level, vector <vector<int>>& result, bool left_to_right) { // 递归往返方向
if (!root)
return;
if (level > result.size())
result.push_back(vector<int>());
if (left_to_right)
result[level - ].push_back(root->val);
else
result[level - ].insert(result[level - ].begin(), root->val);
traverse(root->left, level + , result, !left_to_right);
traverse(root->right, level + , result, !left_to_right);
}
vector<vector<int>> zigzagLevelOrderI(TreeNode *root) {
vector<vector<int>> result;
traverse(root, , result, true);
return result;
} vector<vector<int>> zigzagLevelOrderII(TreeNode *root) { // 迭代版
vector<vector<int>> result;
queue<TreeNode*> current, next;
bool left_to_right = true;
if (root == nullptr)
return result;
else
current.push(root);
while (!current.empty()) {
vector<int> level; // elements in one level
while (!current.empty()) {
TreeNode *node = current.front();
current.pop();
level.push_back(node->val);
if (node->left)
next.push(node->left);
if (node->right)
next.push(node->right);
}
if (!left_to_right) // 多加了这一行
reverse(level.begin(),level.end());
result.push_back(level);
left_to_right = !left_to_right;
swap(next, current);
}
return result;
}
zigzagLevelOrder

zigzagLevelOrder

8,Recover Binary Search Tree

 void inorder(TreeNode* root, vector<TreeNode*>& list, vector<int>& vals) {
if (root == nullptr) return;
inorder(root->left, list, vals);
list.push_back(root);
vals.push_back(root->val);
inorder(root->right, list, vals);
}
void recoverBSTTree(TreeNode* root) {
vector<TreeNode*> list;
vector<int> vals;
sort(vals.begin(), vals.end());
for (size_t i = ; i < list.size(); ++i) {
list[i]->val = vals[i];
}
}

recoverBSTTree

9,Same Tree

 bool isSameTreeI(TreeNode *p, TreeNode *q) {  // 递归版
if (!p && !q)
return true;
if (!p || !q)
return false; return p->val == q->val && isSameTreeI(p->left, q->left) && isSameTreeI(p->right, q->right);
} bool isSampleTreeII(TreeNode *p, TreeNode *q) { // 迭代
stack<TreeNode*> stk;
stk.push(p);
stk.push(q); while (!stk.empty()) {
p = stk.top();
stk.pop();
q = stk.top();
stk.pop(); if (!q && !q)
continue;
if (!q || !p)
return false;
if (q->val != p->val)
return false; stk.push(p->right);
stk.push(q->right); stk.push(p->left);
stk.push(q->left);
}
return true;
}

isSameTree

10,Symmetric Tree(对称树)

 bool isSymmetricI(TreeNode *p, TreeNode *q) {  // 迭代版本
if (!p && !q)
return true;
if (!p || !q)
return false;
return p->val == q->val && isSymmetricI(p->left, q->left) && isSymmetricI(p->right, q->left);
}
bool isSymmetricI(TreeNode *root) {
if (root == nullptr) return true;
return isSymmetricI(root->left, root->right);
} bool isSymmetricII(TreeNode *root) { // 迭代版
if (!root) return true;
stack<TreeNode*> stk;
stk.push(root->left);
stk.push(root->right); while (!stk.empty()) {
auto p = stk.top();
stk.pop();
auto q = stk.top();
stk.pop(); if (!p && !p) continue;
if (!p || !q) return false;
if (p->val != q->val) return false; stk.push(p->left);
stk.push(q->right); stk.push(p->right);
stk.push(q->left);
}
return true;
}

isSymmetric

11,Balanced Binary Tree

 int balancedHeight(TreeNode *root) {
if (root == nullptr)
return ; // 终止条件 int leftHeight = balancedHeight(root->left);
int rightHeight = balancedHeight(root->right); if (leftHeight < || rightHeight < || abs(leftHeight - rightHeight) > ) // 什么时候 leftHight 会小于 0?
return -; // 剪枝 return max(leftHeight, rightHeight) + ; }
bool isBalanceTree(TreeNode *root) {
return balancedHeight(root) >= ;
}

isBalanceTree

12,Flatten Binary Tree to Linked List

 void flatten(TreeNode *root) {  // 迭代版,先序遍历然后组成单链表形状
if (root == nullptr)
return;
stack<TreeNode*> stk;
stk.push(root);
TreeNode dummy(-);
TreeNode *prev = &dummy; while (!stk.empty()) {
TreeNode *node = stk.top();
stk.pop(); if (node->right)
stk.push(node->right);
if (node->left)
stk.push(node->left); node->left = nullptr;
prev->right = node;
prev = prev->right;
}
root = dummy.right;
}

flatten

13,Populating Next Right Pointers in Each Node(II)

 void connectI(TreeLinkNode *root) {  // 迭代版
while (root) {
TreeLinkNode *next = nullptr; // the first node of next level
TreeLinkNode *prev = nullptr; // previous node on the same level
while (root) { // 对于每一行来说
if (!next)
next = root->left ? root->left : root->right; if (root->left) {
if (prev)
prev->next = root->left;
prev = root->left;
}
if (root->right) {
if (prev)
prev->next = root->right;
prev = root->right;
}
root = root->next;
}
root = next; // turn to next level
}
} void connectII(TreeLinkNode *root) { // 迭代版
if (root == nullptr) return; TreeLinkNode dummy(-);
for (TreeLinkNode *curr = root, *prev = &dummy; curr; curr = curr->next) {
if (curr->left) {
prev->next = curr->left;
prev = prev->next;
}
if (curr->right) {
prev->next = curr->right;
prev = prev->next;
}
}
connectII(dummy.next); // 下一层的第一个节点
} connect

connect

14,Construct Binary Tree from Preorder and Inorder Traversal

 TreeNode* buildTreeI(vector<int>::iterator pre_first, vector<int>::iterator pre_last,
vector<int>::iterator in_first, vector<int>::iterator in_last) {
if (pre_first == pre_last) // 如果 左子树为空,结束
return nullptr;
if (in_first == in_last) // 如果 右子树为空,结束
return nullptr; auto root = new TreeNode(*pre_first);
auto inRootPos = find(in_first, in_last, *pre_first);
int leftSize = distance(in_first, inRootPos); root->left = buildTreeI(next(pre_first), next(pre_first, leftSize + ),in_first,next(in_first,leftSize));
root->right = buildTreeI(next(pre_first, leftSize + ), pre_last, next(inRootPos), in_last); return root;
}
TreeNode* buildTreeI(vector<int>& preOrder, vector<int>& inOrder) { // 根据先序遍历和中序遍历序列构造二叉树
return buildTreeI(begin(preOrder), end(preOrder), begin(inOrder), end(inOrder));
}

buildTree

15,Construct Binary Tree from Inorder and Postorder Traversal

 TreeNode* buildTreeII(vector<int>::iterator in_first, vector<int>::iterator in_last,
vector<int>::iterator post_first, vector<int>::iterator post_last) { if (in_first == in_last)
return nullptr;
if (post_first == post_last)
return nullptr; int pRootValue = *prev(post_last);
TreeNode* root = new TreeNode(pRootValue); auto inRootPos = find(in_first, in_last, pRootValue);
int leftSize = distance(in_first, inRootPos); root->left = buildTreeII(in_first, inRootPos, post_first, next(post_first, leftSize)); // 注意迭代器“前闭后开”原则
root->right = buildTreeII(next(inRootPos), in_last, next(post_first, leftSize), prev(post_last)); return root;
}
TreeNode* buildTreeII(vector<int>& inOrder, vector<int>& postOrder) {
return buildTreeII(begin(inOrder), end(inOrder), begin(postOrder), end(postOrder));
}

buildTree

16,Unique Binary Search Trees

 int numTrees(int n) {  // 一维动态规划
vector<int> f(n + , ); f[] = ;
f[] = ;
for (int i = ; i <= n; ++i) {
for (int k = ; k <= i; ++k)
f[i] += f[k - ] * f[i - k];
}
return f[n];
}

numTrees

17,Unique Binary Search Trees II

 vector<TreeNode*> generate(int start, int end) {  // 还未看懂
vector<TreeNode*> subTree;
if (start > end) {
subTree.push_back(nullptr);
return subTree;
}
for (int k = start; k <= end; ++k) { //对每一个节点
vector<TreeNode*> leftSubs = generate(start, k - );
vector<TreeNode*> rightSubs = generate(k + , end);
for (auto i : leftSubs) {
for (auto j : rightSubs) {
TreeNode* node = new TreeNode(k);
node->left = i;
node->right = j;
subTree.push_back(node);
}
}
}
return subTree;
}
vector<TreeNode*> generateTrees(int n) {
if (n == ) return generate(, );
return generate(, n);
}

generate

18,Vaildate Binary Search Tree

 bool isVaildBST(TreeNode* root, int low, int hight) {
if (root == nullptr) return true;
return root->val > low && root->val < hight
&& isVaildBST(root->left, low, root->val)
&& isVaildBST(root->right, root->val, hight);
}
bool isVaildBST(TreeNode* root) {
return isVaildBST(root, INT_MIN, INT_MAX);
}

isVaildBST

19,Convert Sorted Array to Binary Search Tree

 TreeNode* sortedArrayToBST(vector<int>::iterator first, vector<int>::iterator last) {
int length = distance(first, last);
if (length <= ) return nullptr;
auto mid = first + length / ;
TreeNode* root = new TreeNode(*mid);
root->left = sortedArrayToBST(first, mid);
root->right = sortedArrayToBST(mid + , last); return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return sortedArrayToBST(nums.begin(), nums.end());
}

sortedArrayToBST

20,Convert Sorted List to Binary Search Tree

 TreeNode* helper(ListNode* head, ListNode* tail) {
if (head == tail) return nullptr;
ListNode* slow = head, *fast = head;
while (fast->next != tail && fast->next->next != tail) {
slow = slow->next;
fast = fast->next->next;
}
TreeNode* cur = new TreeNode(slow->val);
cur->left = helper(head, slow);
cur->right = helper(slow->next, tail); return cur;
}
TreeNode* sortedListToBST(ListNode* head) {
if (!head) return nullptr;
return helper(head, nullptr);
} TreeNode* sortedListToBST1(ListNode* head) { // 递归
if (!head) return nullptr;
if (!head->next) return new TreeNode(head->val);
ListNode *slow = head, *fast = head, *last = head;
while (fast->next && fast->next->next) {
last = slow;
slow = slow->next;
fast = fast->next->next;
}
fast = slow->next; // slow 指向中间元素的节点,fast 指向下一个链表的起始
last->next = nullptr; // last == slow 将要作为根节点
TreeNode * cur = new TreeNode(slow->val);
if (head != slow) // 此处需要加以判断,否则当左边只有一个节点的时候会出错
cur->left = sortedListToBST1(head);
cur->right = sortedListToBST1(fast); return cur;
}

sortedListToBST

21,Minimum Depth of Binary Tree

 int minDepth(TreeNode* root) { // 递归版
if (!root) return ;
if (!root->left) return + minDepth(root->right);
if (!root->right) return + minDepth(root->left);
return + min(minDepth(root->left), minDepth(root->right));
} int minDepthII(TreeNode* root) { // 层次遍历,记录层次
if (!root) return ;
int minLevel = ;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
++minLevel;
int size = q.size();
for (int i = ; i < size; ++i) {
auto cur = q.front();
q.pop();
if (!cur->left && !cur->right)
return minLevel;
if (cur->left)
q.push(cur->left);
if (cur->right)
q.push(cur->right);
}
}
return -;
}

minDepth

22,Maximum Depth of Binary Tree

 int maxDepth(TreeNode* root) {  // 递归版
if (root == nullptr)
return ;
int leftHeight = maxDepth(root->left);
int rightHeight = maxDepth(root->right);
return + max(leftHeight, rightHeight);
} int maxDepthII(TreeNode* root) { // 迭代版,通过层次遍历来实现
if (root == nullptr)
return ;
queue<TreeNode*> current, next;
int level = ;
current.push(root);
while (!current.empty()) { // 进入每一层
++level;
while (!current.empty()) { // 对每一层的每个节点
TreeNode* node = current.front();
current.pop();
if (node->left)
next.push(node->left);
if (node->right)
next.push(node->right);
}
swap(current, next); // 进入下一层
}
return level;
}

maxDepth

23,Path Sum

 bool hasPathSum(TreeNode* root, int sum) {  //递归版
if (!root) return false;
if (!root->left && !root->right) // 到了叶子节点,进行判断
return sum == root->val;
return hasPathSum(root->left, sum - root->val)
|| hasPathSum(root->right, sum - root->val);
}

hasPathSum

24,Path Sum II

 void pathSum(TreeNode* root, int gap, vector<int>& curr, vector<vector<int>>& result) {
if (root == nullptr) return; curr.push_back(root->val); if (!root->left && !root->right) { // leaf
if (gap == root->val)
result.push_back(curr);
}
pathSum(root->left, gap - root->val, curr, result);
pathSum(root->right, gap - root->val, curr, result);
curr.pop_back(); // 如果到叶子节点,发现不相等,则回退到叶子节点的父节点,并弹出该叶子节点的 val
}
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> result;
vector<int> curr; // 中间结果
pathSum(root, sum, curr, result);
return result;
}

pathSum

25,Binary Tree Maximum Path Sum

 int max_sum = INT_MIN;
int dfs(TreeNode* root) {
if (root == nullptr) return ;
int l = dfs(root->left);
int r = dfs(root->right);
int sum = root->val;
if (l > ) sum += l;
if (r > ) sum += r;
max_sum = max(max_sum, sum);
return max(r, l) > ? max(r, l) + root->val : root->val;
}
int maxPathSum(TreeNode* root) { //还未看懂
max_sum = INT_MIN;
dfs(root);
return max_sum;
}

maxPathSum

26,Populating Next Right Pointers in Each Node

 // 题目同 13,Populating Next Right Pointers in Each Node(II)

connect

27,Sum Root to Leaf Numbers

 int dfs(TreeNode* root, int sum) {
if (root == nullptr) return ;
if (root->left == nullptr && root->right == nullptr)
return sum * + root->val;
return dfs(root->left, sum * + root->val) +
dfs(root->right, sum * + root->val);
}
int sumNumbers(TreeNode* root) {
return dfs(root, );
}

sumNumbers

=============补充=========

1,求两个节点的最近公共祖先节点

 // 求树中任意两个节点的最近公共祖先
// 获取树中节点的路径
bool getNodePath(TreeNode* root, stack<TreeNode*>&stk, TreeNode* p) { // 把路径存入 stk 中,根节点先入栈
if (root == nullptr)
return false; // 递归出口
stk.push(root); if (root->val == p->val)
return true;
bool left = getNodePath(root->left, stk, p);
if (left) // 从左子树找到了
return true;
bool right = getNodePath(root->right, stk, p);
if (right) // 从右子树找到了
return true;
stk.pop(); //回溯
return false;
} // method 1 : the tree is BST
TreeNode* getCommonAncestorI(TreeNode* root, TreeNode*p, TreeNode*q) {
if (root == nullptr)
return nullptr;
else if (p->val >= root->val && q->val <= root->val
|| p->val <= root->val && q->val >= root->val) // 设此 BST 不允许有重复值
return root;
else if (p->val < root->val && q->val < root->val)
getCommonAncestorI(root->left, p, q);
else if (p->val > root->val && q->val > root->val)
getCommonAncestorI(root->right, p, q);
} // method 2 : the tree is triple_link tree(point to parent)
TriTreeNode* getCommonAncestorII(TriTreeNode* root, TriTreeNode* p, TriTreeNode* q) { // 同解法 I
stack<TriTreeNode*> stk1;
stack<TriTreeNode*> stk2;
TriTreeNode* pCurr = p;
TriTreeNode* qCurr = q;
while (pCurr) {
if (pCurr == q)
return pCurr;
else
stk1.push(pCurr);
pCurr = pCurr->parent;
}
while (qCurr) {
if (qCurr == p)
return qCurr;
else
stk2.push(qCurr);
qCurr = qCurr->parent;
}
// 从根节点出栈,比较,最近的公共节点是最后一个相等的出栈元素
TriTreeNode* node = nullptr;
while (!stk1.empty() && !stk2.empty()) {
if (stk1.top() == stk2.top()) {
node = stk1.top();
}
else {
return node;
}
stk1.pop();
stk2.pop();
}
return node;
} // mothod 3 : the tree is oridinary binary tree
// 首先存储两个节点了路径,然后类似方式 II 进行比较
TreeNode* getCommonAncestorIII(TreeNode* root, TreeNode*p, TreeNode*q) {
stack<TreeNode*> stk1;
stack<TreeNode*> stk2;
getNodePath(root, stk1,p);
getNodePath(root, stk2, q); TreeNode* node = nullptr;
int size1 = stk1.size();
int size2 = stk2.size();
int n = abs(size1 - size2);
for (int i = ; i < n; ++i) { // 保证两条链一样长
if (size1 > size2)
stk1.pop();
else
stk2.pop();
}
while (!stk1.empty() && !stk2.empty()) { // 寻找最近的父节点
if (stk1.top() == stk2.top())
return stk1.top();
else
stk1.pop();
stk2.pop();
}
return stk1.top();
}

getCommonAncestor

以上题目均来源于:https://www.github.com/soulmachine/leetcode(leetcode-cpp.pdf)

note:补充部分题目不来源于此书

最新文章

  1. vmware下的centos上网配置
  2. C# winform OpenFileDialog MessageBox
  3. codeforces 493B.Vasya and Wrestling 解题报告
  4. PHP面向对象学习六 多态
  5. CodeSmith 7.01破解下载
  6. jquery如何通过name名称获取当前name的value值
  7. 13. 求链表倒数第k个节点
  8. UITabBar的隐藏
  9. 关于委托:异常{ 无法将 匿名方法 转换为类型&ldquo;System.Delegate&rdquo;,因为它不是委托类型 }
  10. pythong下的unittest框架
  11. HBase Region级别二级索引
  12. Miller Rabin算法详解
  13. Centos6.5升级openssh、OpenSSL和wget
  14. Linux命令:readonly
  15. 关于MySQL卸载重新安装的问题
  16. codeforces116B
  17. Hbase记录-Hbase shell使用
  18. linux crypt()函数使用总结
  19. [LeetCode&amp;Python] Problem 733. Flood Fill
  20. IIS快捷方式

热门文章

  1. socket-tcp
  2. add_featurelayer_to_map
  3. Python linux 上的管理工具 pyenv 安装, pip 使用, python项目(版本分割, 项目分割, 虚拟环境创建)
  4. Dubbo 服务容错Hystrix
  5. sql server 字符串字节长度
  6. 后台设计的基石:用户权限管理(RBAC)及工作流(workflow)模型
  7. 查找nginx安装的路径
  8. centos服务器如何用命令查看哪个程序内存占用情况,硬盘空间占用
  9. 爬虫--Scrapy-持久化存储操作
  10. UnicodeDecodeError: &#39;ascii&#39; codec can&#39;t decode byte 0x9c in position 1: ordinal not in range(128)