目录

前言:

先序创建二叉树

二叉树遍历(前|中|后 序)--递归(核心代码)

二叉树遍历(前|中|后|层 序)--非递归(核心代码)

后序 双栈法

点这里有个C++ 版,方法很多,只会C的话应该能看懂思路

点这里有思路清晰的C语言版本

点这里有个后续遍历的不错思路——节点里增加了一个变量记录次数(或者用哈希表也可以)

求二叉树高度

按树状打印二叉树

输出二叉树叶子节点并统计叶子节点的数目

哈夫曼树(编码)

二叉搜索树--递归--插入,删除,和查找

二叉搜索树--非递归--插入、删除和查找

由前序中序重建二叉树

由中序后序重建二叉树

【Morris_Traversal】二叉树遍历(前|中|后 序)--非递归--不用栈--(完整代码)

前言:

排版很难看,没办法,主要是因为。。。。。。算了不解释了我就是懒。


先序创建二叉树

(这里用了C++  <引用>的特性,使用二重指针代替或者将函数返回值设成指针再做点小修改也能实现)

void CreateTree(TreeRoot &Root)
{//创建(先序)char c;c=getchar();if(c!='#'){Root=(TreeRoot)malloc(sizeof(TNode));Root->data=c;CreateTree(Root->pleft);CreateTree(Root->pright);}else{Root=NULL;}
}

二叉树遍历(前|中|后 序)--递归(核心代码)

void InorderTraversal( BinTree BT )
{if( BT ) {InorderTraversal( BT->Left );/* 此处假设对BT结点的访问就是打印数据 */printf("%d ", BT->Data); /* 假设数据为整型 */InorderTraversal( BT->Right );}
}void PreorderTraversal( BinTree BT )
{if( BT ) {printf("%d ", BT->Data );PreorderTraversal( BT->Left );PreorderTraversal( BT->Right );}
}void PostorderTraversal( BinTree BT )
{if( BT ) {PostorderTraversal( BT->Left );PostorderTraversal( BT->Right );printf("%d ", BT->Data);}
}————————————————
版权声明:本文为CSDN博主「BrianOne」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Brianone/article/details/89440024

二叉树遍历(前|中|后|层 序)--非递归(核心代码)

void PreOrderFDG(TreeRoot Root)
{//先序遍历非递归SqStack S;InitStack(S);while(Root!=NULL || Empty(S)==0){if(Root!=NULL){printf("%c ",Root->data);Push(S,Root);Root=Root->pleft;}else{Pop(S,Root);Root=Root->pright;}}
}
void InOrderFDG(TreeRoot Root)
{//中序遍历非递归SqStack S;InitStack(S);while(Root!=NULL || Empty(S)==0){if(Root!=NULL){Push(S,Root);Root=Root->pleft;}else{Pop(S,Root);printf("%c ",Root->data);Root=Root->pright;}}
}
//后序遍历非递归算法
typedef struct SNode{BiTree p;int tag;
}SNode;
//后序遍历使用的进栈函数
void postpush(SNode *a,SNode sdata){a[++top]=sdata;
}
//后序遍历函数
void PostOrderTraverse(BiTree Tree){SNode a[20];//定义一个顺序栈BiTNode * p;//临时指针int tag;SNode sdata;p=Tree;while (p||top!=-1) {while (p) {//为该结点入栈做准备sdata.p=p;sdata.tag=0;//由于遍历是左孩子,设置标志位为0postpush(a, sdata);//压栈p=p->lchild;//以该结点为根结点,遍历左孩子}sdata=a[top];//取栈顶元素pop();//栈顶元素弹栈p=sdata.p;tag=sdata.tag;//如果tag==0,说明该结点还没有遍历它的右孩子if (tag==0) {sdata.p=p;sdata.tag=1;postpush(a, sdata);//更改该结点的标志位,重新压栈p=p->rchild;//以该结点的右孩子为根结点,重复循环}//如果取出来的栈顶元素的tag==1,说明此结点左右子树都遍历完了,可以调用操作函数了else{displayElem(p);p=NULL;}}
}

后序 双栈法

void NotRecursionPostOrder(BTree T){PLinkStack S,CS;S=Init_Stack();CS=Init_Stack();while(T || !empty_Stack(S)){if(T){Push_Stack(S,T);Push_Stack(CS,T);T=T->right;}else{T=Pop_Stack(S)->data;T=T->left;}}while(CS->top!=NULL){printf("%c",CS->top->data->element);CS->top=CS->top->next;}DestroyStack(CS);
}
void LevelorderTraversal ( BinTree BT )//层序遍历
{Queue Q;BinTree T;if ( !BT ) return; /* 若是空树则直接返回 */Q = CreatQueue(); /* 创建空队列Q */AddQ( Q, BT );while ( !IsEmpty(Q) ) {T = DeleteQ( Q );printf("%d ", T->Data); /* 访问取出队列的结点 */if ( T->Left )   AddQ( Q, T->Left );if ( T->Right )  AddQ( Q, T->Right );}————————————————
版权声明:本文为CSDN博主「BrianOne」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Brianone/article/details/89440024

点这里有个C++ 版,方法很多,只会C的话应该能看懂思路

点这里有思路清晰的C语言版本

点这里有个后续遍历的不错思路——节点里增加了一个变量记录次数(或者用哈希表也可以)

后序遍历方法挺多,多搜一搜,特别是C++ 代码最好也能看看,有很多优秀的实现都是c++版的。

求二叉树高度

int PostTreeDepth(TreeRoot Root)
{//求二叉树的高度int hl,hr,max;if(Root!=NULL){hl=PostTreeDepth(Root->pleft);hr=PostTreeDepth(Root->pright);max=hl>hr?hl:hr;return max+1;}elsereturn 0;
}

按树状打印二叉树

void PrintTree(TreeRoot Root,int nLayer)
{//按树状打印二叉树int i;if(Root==NULL)return ;PrintTree(Root->pright,nLayer+1);for(i=0;i<=nLayer;i++){printf("  ");}printf("%c\n",Root->data);PrintTree(Root->pleft,nLayer+1);
}

输出二叉树叶子节点并统计叶子节点的数目

void PreOrderLeaf(TreeRoot Root)
{//输出二叉树的叶子结点,并统计叶子结点的数目if(Root!=NULL){if(Root->pleft==NULL && Root->pright==NULL){printf("%c ",Root->data);leafcount++;}PreOrderLeaf(Root->pleft);PreOrderLeaf(Root->pright);}
}

哈夫曼树(编码)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
typedef struct hfNode {int weight;struct hfNode* lch, * rch, * pnt;
}hfNode;void selMin(hfNode* nodes, int n, int* a, int* b) { //求两个最小值的下标int temp[3] = { 0x3f3f3f3f,0x3f3f3f3f,0x3f3f3f3f };int i;for (i = 0; i < n; ++i) {//printf("%d,%d;", temp[1], temp[2]);if (nodes[i].pnt == 0) {int t = nodes[i].weight;if (temp[1] == 0x3f3f3f3f) {temp[1] = t;*a = i;}else if (temp[2] == 0x3f3f3f3f) {temp[2] = t;*b = i;}else if (temp[1] > t) {temp[1] = t;*a = i;}else if (temp[2] > t) {temp[2] = t;*b = i;}}//printf("%d,%d;\n", temp[1], temp[2]);}
}void CreateTree(hfNode* nodes, char** hfCode, int* w, int n) {  //构造 Huffman Tree   规定向左走则生成0  右 1int m = 2 * n - 1;int j;int len;char* helper = (char*)malloc(2 * n * sizeof(char));for (int i = n; i < m; ++i) {int a, b;selMin(nodes, m, &a, &b);nodes[i].pnt = 0;nodes[i].lch = &nodes[a];nodes[i].rch = &nodes[b];nodes[a].pnt = &nodes[i];nodes[b].pnt = &nodes[i];nodes[i].weight = nodes[a].weight + nodes[b].weight;}//树建立完毕 下面开始生成哈夫曼码for (int i = 0; i < n; ++i) {hfNode* cur = nodes + i;j = 0;while (cur->pnt != 0) {hfNode* p = cur->pnt;if (p->lch == cur) {helper[j++] = '0';}else {helper[j++] = '1';}cur = cur->pnt;}hfCode[i] = (char*)malloc(sizeof(char) * (j + 1));len = 0;while (j > 0) {hfCode[i][len++] = helper[--j];}hfCode[i][len] = '\0';}free(helper);
}
void show(char** hfCode, int n) {//int n;int i;printf("\n按照输入顺序   哈夫曼编码依次为:\n");//printf("%d,%d\n", sizeof(hfCode) , sizeof(char*));//n = sizeof(hfCode) / sizeof(char*);for (i = 0; i < n; ++i) {printf("%s\n", hfCode[i]);}printf("\n================================\n");
}
void main() {hfNode* nodes;char** hfCode;int n;int* w;int i;printf("请输入字符数量:\n");scanf("%d", &n);w = (int*)malloc(n * sizeof(char*));hfCode = (char**)malloc(n * sizeof(char*));nodes = (hfNode*)malloc((2 * n - 1) * sizeof(hfNode));printf("请依次输入字符权重:\n");for (i = 0; i < n; ++i) {scanf("%d", w + i);(nodes + i)->weight = w[i];(nodes + i)->lch = (nodes + i)->rch = (nodes + i)->pnt = 0;}CreateTree(nodes, hfCode, w, n);show(hfCode, n);printf("%p,%p", (nodes + 1)->pnt, (nodes + 3)->pnt);free(w);free(nodes);free(hfCode);}
/*
A  B  C  D
3  1  2  1
应该的编码之一应该为:0
101
11
100
*/

二叉搜索树--递归--插入,删除,和查找

//二叉查找树   递归实现  插入,删除和查找
#include<stdio.h>
#include<stdlib.h>typedef struct Node {int val;struct Node* left;struct Node* right;
}Node;
typedef int bool;Node * Find(Node* root,int a);   //如果找到了返回指针 如果找不到则返回空指针
Node *Insert(Node* root, int a);  //将a插入到root中并且返回根节点指针
Node *Delete(Node* root,int a);   //将a从root中删除并且返回根节点指针
Node* FindMin(Node* root);//找到最小节点并且返回该节点的指针
Node* FindMax(Node* root);//找到最大节点并且返回该节点的指针
void PreorderTraversal(Node* root); //先序遍历
int main(){Node* root = (Node*)malloc(sizeof(Node));//根节点Node * BST, *MinP, *MaxP, *Tmp;   //分别是树根节点   最小节点 最大节点 和一个临时用的节点指针变量int X;int N, i;BST = NULL;scanf("%d", &N);//插入节点for (i = 0; i < N; i++) {scanf("%d", &X);BST = Insert(BST, X);}printf("Preorder:"); PreorderTraversal(BST); printf("\n");//先序遍历MinP = FindMin(BST);MaxP = FindMax(BST);scanf("%d", &N);//查找节点for (i = 0; i < N; i++) {scanf("%d", &X);Tmp = Find(BST, X);if (Tmp == NULL) printf("%d is not found\n", X);else {printf("%d is found\n", Tmp->val);if (Tmp == MinP) printf("%d is the smallest key\n", Tmp->val);if (Tmp == MaxP) printf("%d is the largest key\n", Tmp->val);}}scanf("%d", &N);//删除节点for (i = 0; i < N; i++) {scanf("%d", &X);BST = Delete(BST, X);}printf("Preorder:"); PreorderTraversal(BST); printf("\n");//先序遍历return 0;
}Node *Find(Node* root,int a) { //查找if (!root) return NULL;if (a == root->val) {return root;}else if (a > root->val) {return Find(root->right, a);}else {//a< root->valreturn Find(root->left, a);}return NULL;//实际上这一行是没有必要的
}
Node *Insert(Node* root, int a) {if (!root) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->val = a;newNode->left = newNode->right = NULL;return newNode;}else if (a > root->val) {root->right = Insert(root->right, a);}else if (a < root->val) {root->left = Insert(root->left, a);}else {//这时候root的节点值等于a则不处理}return root;
}
Node* Delete(Node* root, int a) {if (!root) return root;if (a < root->val)       root->left = Delete(root->left, a);else if(a > root->val)   root->right = Delete(root->right, a);else{  //找到这个节点  那么进行删除操作  此刻要考虑四种情况:左右空 左右非空 左空右非空 左非空右空if (!root->left) { Node* temp = root; root = root->right; free(temp); }else if (!root->right) { Node* temp = root; root = root->left;free(temp); }else {Node* temp = root->right;while (temp->left) {temp = temp->left;}temp->left = root->left;root = root->right;}}return root;//这一句实际上没有必要
}
Node* FindMin(Node* root) {if (!root) {return NULL;}if (!root->left) {return root;}return FindMin(root->left);
}
Node* FindMax(Node* root) {if (!root) {return NULL;}if (!root->right) {return root;}return FindMax(root->right);
}
void PreorderTraversal(Node* root) {if (!root) return;printf("%d  ", root->val);PreorderTraversal(root->left);PreorderTraversal(root->right);
}

二叉搜索树--非递归--插入、删除和查找

#define _CRT_SECURE_NO_WARNINGS
//二叉查找树   非递归实现  插入,删除和查找
#include<stdio.h>
#include<stdlib.h>typedef struct Node {int val;struct Node* left;struct Node* right;
}Node;
typedef int bool;Node* Find(Node* root, int a);   //如果找到了返回指针 如果找不到则返回空指针
Node* Insert(Node* root, int a);  //将a插入到root中并且返回根节点指针
Node* Delete(Node* root, int a);   //将a从root中删除并且返回根节点指针
Node* FindMin(Node* root);//找到最小节点并且返回该节点的指针
Node* FindMax(Node* root);//找到最大节点并且返回该节点的指针
void PreorderTraversal(Node* root); //先序遍历
int main() {Node* root = (Node*)malloc(sizeof(Node));//根节点Node* BST, * MinP, * MaxP, * Tmp;   //分别是树根节点   最小节点 最大节点 和一个临时用的节点指针变量int X;int N, i;BST = NULL;scanf("%d", &N);//插入节点for (i = 0; i < N; i++) {scanf("%d", &X);BST = Insert(BST, X);}printf("Preorder:"); PreorderTraversal(BST); printf("\n");//先序遍历MinP = FindMin(BST);MaxP = FindMax(BST);scanf("%d", &N);//查找节点for (i = 0; i < N; i++) {scanf("%d", &X);Tmp = Find(BST, X);if (Tmp == NULL) printf("%d is not found\n", X);else {printf("%d is found\n", Tmp->val);if (Tmp == MinP) printf("%d is the smallest key\n", Tmp->val);if (Tmp == MaxP) printf("%d is the largest key\n", Tmp->val);}}scanf("%d", &N);//删除节点for (i = 0; i < N; i++) {scanf("%d", &X);BST = Delete(BST, X);}printf("Preorder:"); PreorderTraversal(BST); printf("\n");//先序遍历return 0;
}
Node* Find(Node* root, int a) { //查找if (!root) return NULL;while (root) {if (a == root->val) {break;}else if (a > root->val) {root = root->right;}else {//a< root->valroot = root->left;}}return root;
}
Node* Insert(Node* root, int a) {if (!root) {root = (Node*)malloc(sizeof(Node));root->val = a;root->left = root->right = NULL;}else {Node* cur = root;Node* pre = NULL;while (cur) {if (a > cur->val) {pre = cur;cur = cur->right;}else if (a < cur->val) {pre = cur;cur = cur->left;}else {break;//找到了值为a的节点}}if (!cur) {  //如果没有找到 则插入if (a < pre->val) {pre->left = (Node*)malloc(sizeof(Node));pre->left->left = pre->left->right = NULL;pre->left->val = a;}else {pre->right = (Node*)malloc(sizeof(Node));pre->right->left = pre->right->right = NULL;pre->right->val = a;}}}return root;
}
Node* Delete(Node* root, int a) {//为什么代码这么长?因为没用到递归也没用到引用 就需要一个preif (!root) return root;//根节点为空Node* pre = NULL;Node* cur = root;while (cur) {if (a < cur->val) {pre = cur;cur = cur->left;}else if (a > cur->val) {pre = cur;cur = cur->right;}else {if ((!cur->left) && (!cur->right)) {if (!pre) {//cur为根节点free(cur);return pre;}if (a < pre->val) {pre->left = NULL;}else {pre->right = NULL;}return root;}else if (!cur->right) {if (!pre) {cur = cur->left;free(root);return cur;}if (a < pre->val) {pre->left = cur->left;free(cur);}else {pre->right = cur->left;free(cur);}return root;}else if (!cur->left) {if (!pre) {cur = cur->right;free(root);return cur;}if (a < pre->val) {pre->left = cur->right;free(cur);}else {pre->right = cur->right;free(cur);}return root;}else {Node* temp = cur->left;while (temp->right) {temp = temp->right;}temp->right = cur->right;if (!pre) { Node* t = cur->left; free(cur); return t; };if (a < pre->val) {pre->left = cur->left;}else {pre->right = cur->left;}free(cur);return root;}}}return root;
}
Node* FindMin(Node* root) {if (!root) {return NULL;}while (root->left) {root = root->left;}return root;
}
Node* FindMax(Node* root) {if (!root) {return NULL;}while (root->right) {root = root->right;}return root;
}
void PreorderTraversal(Node* root) {if (!root) return;printf("%d  ", root->val);PreorderTraversal(root->left);PreorderTraversal(root->right);
}

由前序中序重建二叉树

由中序后序重建二叉树

【Morris_Traversal】二叉树遍历(前|中|后 序)--非递归--不用栈--(完整代码)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define DataType int
#define nullptr 0
#define MAXN 2048
typedef struct node {DataType data;struct node* pleft;struct node* pright;
}TNode, * TreeRoot;
TNode* CreateTree() {//构建二叉树  (先序)int a;scanf("%d", &a);if (a != -1){TNode* ne = (TNode*)malloc(sizeof(TNode));ne->data = a;ne->pleft = CreateTree();ne->pright = CreateTree();return ne;}return nullptr;
}
void traversal_pre(TNode * root) { //先序遍历二叉树morris_traversal  (已过测试集)while (root) {if (root->pleft) {TNode* rightmost = root->pleft;while (rightmost->pright&&rightmost->pright!=root) {rightmost = rightmost->pright;}if (rightmost->pright) {rightmost->pright = nullptr;root = root->pright;}else {printf("%d ", root->data); //输出数据rightmost->pright = root;root = root->pleft;}}else {printf("%d ", root->data); //输出数据root = root->pright;}}
}
void traversal_mid(TNode* root) { //中序遍历二叉树morris_traversal  (已过测试集)while (root) {if (root->pleft) {TNode* rightmost = root->pleft;while (rightmost->pright && rightmost->pright != root) {rightmost = rightmost->pright;}if (rightmost->pright) {rightmost->pright = nullptr;printf("%d ", root->data); //输出数据root = root->pright;}else {rightmost->pright = root;root = root->pleft;}}else {printf("%d ", root->data); //输出数据root = root->pright;}}
}
void traversal_pos(TNode* root) { //后序遍历二叉树morris_traversal    (已过测试集)int temp[MAXN];int n = 0;while (root) {if (root->pright) {TNode* lm = root->pright;while (lm->pleft&&lm->pleft != root) {lm = lm->pleft;}if (lm->pleft) {lm->pleft = nullptr;root = root->pleft;}else {lm->pleft = root;//printf("%d", root->data);temp[n++] = root->data;root = root->pright;}}else {temp[n++] = root->data;root = root->pleft;}}while (n) {printf("%d ", temp[--n]);}
}
int main() {TNode * tree = CreateTree();  //创建二叉树//traversal_pre(tree);//traversal_mid(tree);traversal_pos(tree);//system("pause");return 0;
}
/*
空树: -1==============1:1 -1 -1
先序遍历结果; 1
中序遍历结果: 1
后序遍历结果:1
=======================12:1 2 -1 -1 -1
先序遍历结果: 1  2
中序遍历结果: 2  1
后序遍历结果:2  1
=======================12:1 -1 2 -1 -1
先序遍历结果: 1  2
中序遍历结果: 1  2
后序遍历结果:2  1
=======================12      34   5  6:1 2 -1 4 -1 -1 3 5 -1 -1 6 -1 -1
先序遍历结果:1  2  4  3  5  6
中序遍历结果:2  4  1  5  3  6
后序遍历结果: 4  2  5  6  3  1
*/

《数据结构》树和二叉树代码整理(C语言实现)相关推荐

  1. 王道——数据结构——树与二叉树(3)

    系列文章目录 其他章节相关文章 王道--数据结构--栈和队列(1) 本章节其他相关文章 王道--数据结构--树与二叉树(1) 王道--数据结构--树与二叉树(2) 王道--数据结构--树与二叉树(4) ...

  2. 数据结构-树与二叉树-思维导图+小结

    数据结构-树与二叉树-思维导图 1 数据结构-第五章-树与二叉树-思维导图 2 思维导图-补充 3 小结 3.1 知识点小结 3.2 习题小结 1 数据结构-第五章-树与二叉树-思维导图   数据结构 ...

  3. 数据结构——树和二叉树章节思维导图

    数据结构--树和二叉树章节思维导图

  4. C语言 数据结构 树和二叉树

    树 1.树:是n节点的有限集.树是n(n=>0)个节点的有限集. n=0时成为空树. 在任意一颗非空树中:(1)有且仅有一个称为根的节点:(2)当n>0时,其余节点可分为m(m>0) ...

  5. 数据结构——树与二叉树

    树与二叉树 一.树的定义: 1.定义:树(Tree)是n(n>=0)个节点的有限集,n=0时称为"空树".在任意一棵非空树中: ⒈有且仅有一个特定的称为根(root)的节点. ...

  6. 数据结构—树与二叉树

    总第119篇 前言 之前谈到的线性表.栈和队列都是一对一的数据结构,但是现实中也存在很多一对多的数据结构,这篇要写的就是一种一对多的数据结构---树.全文分为如下几部分: 树的一些基本概念 树的存储结 ...

  7. 数据结构-树,二叉树,森林

    树,二叉树,森林 王卓老师的数据结构课程笔记 树和二叉树 定义 结点之间有分支,具有层次关系 是n个结点的有限集. 若n = 0,称为空树: 若n > 0,则它满足如下两个条件: 有且仅有一个特 ...

  8. Python数据结构与算法笔记(八):数据结构——树,二叉树和AVL树

    树 class Node:def __init__(self, name, type='dir'):self.name = nameself.type = type #"dir" ...

  9. 【数据结构 - 树和二叉树】自学笔记记录(完结)

    目录 一.树和二叉树的定义 1.树的基本术语 2.二叉树的定义 4.二叉树的性质 满二叉树 完全二叉树 5.树和二叉树的区别 二.遍历二叉树和线索二叉树 1.创建二叉树 2.遍历二叉树 1.前序遍历 ...

最新文章

  1. Java多线程协作CountDownLatch,主线程等待子线程结束
  2. 机器人达到指定位置方法数
  3. linux如何删除boot分区,怎么清理boot分区
  4. 转: telnet命令学习
  5. labeme批量转换json文件_Python实现markdown文件批量转换为word
  6. C#語法學習二(NameSpace)
  7. html脚本类型,HTML脚本标记:类型或语言(或省略两者)?
  8. java 二进制置位,重置
  9. php文件流播放拖动,自定义实现可以播放暂停、进度拖拽、音量控制及全屏的H5播放器...
  10. 全国大数据分析系统基于vue echarts
  11. 做一个iframe的弹出框
  12. 【转载】偏最小二乘法回归(Partial Least Squares Regression)
  13. 在RFID标准协议中 ISO18000-6B和ISO18000-6C的优点及区别
  14. FFmpeg 和 MP4Box 几个命令
  15. astrolog32 java_Astrolog32下载
  16. 判断链表是否中心对称(21.6.8)
  17. 组装机怎么重装系统?组装机U盘装系统方法
  18. Vue2.0 的 Material Design UI 组件库 Muse-UI
  19. (比较器)Comparator比较器
  20. Docker实现原理之 - OverlayFS实现原理

热门文章

  1. Java面试补给站——final、volatile、synchronized三大关键字
  2. 原生支持Linux的音乐软件,Linux 下五款轻量级音乐播放器(开源)
  3. 程序员在 Github 上疯狂薅羊毛!
  4. 4链提币接口通道源码
  5. 漫画:什么是B+树,B+树层数计算(面试官直呼内行)
  6. 无法停止服务 请求的控件对此服务无效
  7. 《机器学习系列教程》:第二章 机器学习基础
  8. 外敌重重自绊自脚?HTML5普及的血泪史
  9. linux系统禁止邮箱服务,Linux禁止smtp发送邮件,禁止25端口,防止垃圾邮件
  10. 7个实用又鲜为人知的PPT技巧