· (tree)是n(n>=0)个结点的有限集。当n=0时成为空树,在任意一颗非空树中:

//这里只需掌握定义,重点在二叉树

-有且仅有一个特定的称为根(Root)的结点;

-当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、...、Tm,

其中集合本身又是一棵树,并且称为根的子树(SubTree)。

- n>0时,根结点是唯一的,坚决不可能存在多个根结点。

- m>0时,子树的个数是没有限制的,但它们互相是一定不会相交的。

· 结点拥有的子树称为结点的度(Degree),树的度取树内各结点的度的最大值 。

-度为0的结点称为叶结点(Leaf)或终端结点。

-度不为0的结点称为分支结点或非终端结点,除根结点外 ,分支结点也称为内部结点。

· 结点的子树的根称为结点的孩子(Child),相应的,该结点称为孩子的双亲(Parent),

同一双亲的孩子之间互称为兄弟(Sibling)。

· 结点的祖先是从根到该结点所经分支上的所有结点。

· 结点的层次(Level)从根开始定一起,根为第一层,根的孩子为第二层。

· 其双亲在同一层的结点互为堂兄弟。

· 树中结点的最大层次称为树的深度(Depth)或高度。

· 如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称该树

为有序树,否则称为无序树。

二叉树

定义

· 二叉树是n(n>=0)个结点 的 有限集合,该集合或者为空集(空二叉树),或者由

一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。

特点

· 每个结点 最多 有两棵子树,所以二叉树中不存在度大于2的结点。

· 左子树和右子树是有顺序的,次序不能颠倒。

· 即使树中某节点只有一棵子树,也要区分它是左子树还是右子树。

五种基本形态

· 空二叉树

· 只有一个根结点

· 根结点只有左子树

· 根结点只有右子树

· 根结点既有左子树又有右子树

满二叉树

-在一棵二叉树中,如果所有分支点都存在左子树和右子树,并且所有叶子都在同一层上,

这样的二叉树称为满二叉树。

· 满二叉树的特点有:

-叶子只能出现在最下一层。

-非叶子结点的度一定是2。

-在同样深度的二叉树中,满二叉树的结点个数一定最多,同时叶子也是最多。

完全二叉树

· 对一棵具有n个结点的二叉树按层序编号,如果编号为i(1<=i<=n)的结点与同样深度的满二叉树

中编号为i的结点位置完全相同,则这颗 二叉树称为完全二叉树。

· 完全二叉树的特点有:

-叶子结点只能出现在最下两层。

-最下层的叶子一定集中在左部连续位置。

-倒数第二层,若有叶子结点,一定都在右部连续位置。

-如果结点度为1,则该结点只有左孩子。

-同样结点数的二叉树,完全二叉树的深度最小。

· 注意:满二叉树一定是完全二叉树,但完全二叉树不一定是满二叉树。

二叉树的性质

· 性质一:在二叉树的第i层上至多有2^(i-1)个结点(i>=1)。

· 性质二:深度为k的二叉树至多有2^k-1个结点(k>=1)。

· 性质三:对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。

-推导过程

-首先再假设度为1的结点数为n1,则二叉树T的结点总数n=n0+n1+n2

-其次发现连接树总是等于总结点数n-1,并且等于n1+2*n2

-所以n-1=n1+2*n2

-所以n0+n1+n2-1=n1+n2+n2

-最后n0=n2+1

· 性质四:具有n个结点的完全二叉树的深度为取下整的(log2n)+1

-由满二叉树的定义结合性质二可得,深度为k的满二叉树的结点树n一定是2^k-1。

-对于满二叉树可以通过n=2^k-1推得满二叉树的深度为k=log2(n+1)

-对于倒数第二层的满二叉树我们同样很容易回推出它的结点数为n=2^(k-1)-1

-所以完全二叉树的结点数的取值范围是:2^(k-1)-1<n<=2^k-1

-由于n是整数,n<=2^k-1可以看成n<2^k

-同理2^(k-1)-1<n可以看成2^(k-1)<=n

-所以2^(k-1)<=n<2^k

-不等式 两边同时取对数,得到k-1<=log2n<k

-由于k是深度,必须取整,所以k为取下整的(log2n)+1

· 性质五:如果对一棵有n个结点的完全二叉树(其深度为(log2n)+1)的结点

按层序编号,对任一结点i(1<=i<=n)有以下性质:

-如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲结点[i/2]取下整

-如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子结点是2i

-如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1

二叉链表

存储结构:

typedef char TElemType;
typedef struct BiTNode{TElemType data;BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;

创建一个二叉树

void CreateBiTree(BiTree &T){//按先序遍历输入结点,左孩子或右孩子为空,用空格代替char c;scanf("%c",&c);if(c==' '){//如果为空格,则指向的左孩子或者右孩子为空T=NULL;} else{//创建结点,按照先序遍历创建T=(BiTree)malloc(sizeof(BiTNode));if(!T)exit(0);T->data=c;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}
}

二叉树的遍历

· 二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得

每个结点被访问一次且仅被访问一次。

· 二叉树的遍历次序不同于线性结构,线性结构最多也就是分为顺序、循环、双向等

简单的遍历方式。

· 树的结点之间不存在唯一的前驱和后继这样的关系,在访问一个结点后,下一个被

访问的结点面临着不同的选择。

· 二叉树的遍历方式可以很多,主要有下面三种:

· 前序遍历

-若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。

· 中序遍历

-若树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点),中序

遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树。

· 后序遍历

-若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后根结点。

先序遍历:ABCDEFGHK

中序遍历:BDCAEHGKF

后序遍历:DCBHKGFEA

递归遍历算法代码实现:

void  PrintElement(TElemType e){printf("%c",e);
}void PreOrderTraverse(BiTree T){if(T){//先序遍历//三种遍历方式只不过更换下面三句语句的顺序PrintElement(T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}
}
void InOrderTraverse(BiTree T){//中序遍历if(T){InOrderTraverse(T->lchild);PrintElement(T->data);InOrderTraverse(T->rchild);}
}void PostOrderTraverse(BiTree T){//后序遍历if(T){PostOrderTraverse(T->lchild);PostOrderTraverse(T->rchild);PrintElement(T->data);}
}

非递归的两种算法:

· 另需定义一个栈,存储结点

#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10   //存储空间分配增量
typedef struct {BiTree *base;    //在栈构造之前和销毁之后,base值为NULLBiTree *top;     //栈顶指针int stacksize;      //当前已分配的存储空间,以元素为单位
} SqStack;
int InitStack(SqStack &S) {//构造一个空栈SS.base = (BiTree *) malloc(STACK_INIT_SIZE * sizeof(BiTree));//存储分配失败if (!S.base)exit(0);S.top = S.base;S.stacksize = STACK_INIT_SIZE;return 1;
}int Push(SqStack &S, BiTree e) {//插入元素e为新的栈顶元素if (S.top - S.base >= S.stacksize) {//栈满,追加存储空间S.base = (BiTree *) realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(BiTree));//出错退出if (!S.base)exit(0);//使top指针重新回到栈顶S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top++ = e;//赋值后,指针上移return 1;
}int Pop(SqStack &S, BiTree &e) {//若栈不为空,则删除S的栈顶元素,用e返回其值//并返回1,否则返回0if (S.top == S.base)return 0;//top指针下移,并赋值给ee = *--S.top;return 1;
}int GetTop(SqStack S, BiTree &e) {//若栈不空,则用e返回S的栈顶元素,并返回1,否则返回0if (S.top == S.base)return 0;e = *(S.top - 1);return 1;
}int StackEmpty(SqStack S) {//判断栈是否为空,空则返回1,否则返回0if (S.base == S.top)return 1;elsereturn 0;
}
void unInOrderTraverse1(BiTree T){//采用二叉链表存储结构//中序遍历二叉树T的非递归 算法//方法1SqStack S;BiTree p;InitStack(S);//创建栈Push(S,T);//头结点入栈while (!StackEmpty(S)){//当栈非空时while (GetTop(S,p)&&p)//把栈顶元素给p,且p存在Push(S,p->lchild);//一直往左,直到尽头Pop(S,p);//空指针出栈if(!StackEmpty(S)){//判断是否空栈Pop(S,p);//最左边的一个结点出栈if(!p->data)//访问结点exit(0);elsePrintElement(p->data);Push(S,p->rchild);//该结点的右子树进栈}}
}void unInOrderTraverse2(BiTree T){//采用二叉链表存储结构//中序遍历二叉树T的非递归 算法//方法2SqStack S;BiTree p;//创建栈InitStack(S);p=T;while (p||!StackEmpty(S)){if(p){//根指针进栈,遍历左子树Push(S,p);p=p->lchild;} else{//根指针退栈,访问根结点 ,遍历右子树Pop(S,p);if(!p->data)exit(0);elsePrintElement(p->data);p=p->rchild;}}
}

线索二叉树

普通二叉树在叶子结点中存在空指针,造成了空间浪费,线索二叉树把这些利用起来

并且能提高遍历的效率。就像链表一样,直接指示下一个结点的位置。

需要增加两个标识域

· LTage 为0  lchild域指示结点的左孩子

· LTage 为1  lchild域指示结点的前驱

· RTage 为0  rchild域指示结点的右孩子

· RTage 为1  rchild域指示结点的后继

结构体代码:

typedef char TElemType;
//Link为0表示左右孩子的指针
//Thread为1表示前驱后继的线索
enum PointerTag {Link, Thread
};
typedef struct BiThrNode {TElemType data;struct BiThrNode *lchild, *rchild;PointerTag LTag, RTag;
} BiThrNode, *BiThrTree;

中序遍历线索化以及中序遍历二叉线索树T的非递归算法

//全局变量,始终指向刚刚访问过的结点
BiThrTree pre;void CreateBiThrTree(BiThrTree &T) {//遵循前序遍历约定输入char c;scanf("%c", &c);if (c == ' ')T = NULL;else {T = (BiThrTree) malloc(sizeof(BiThrNode));if (!T)exit(0);T->data = c;printf("%c", c);//先默认它有左右子树T->LTag = Link;T->RTag = Link;CreateBiThrTree(T->lchild);CreateBiThrTree(T->rchild);}
}//中序遍历线索化
void InTreading(BiThrTree p) {if (p) {//递归左孩子线索化InTreading(p->lchild);//如果该结点没有左孩子,设置LTag为Thread,// 并把lchild指向刚刚访问的结点,设为前驱if (!p->lchild) {p->LTag = Thread;p->lchild = pre;}//如果该结点没有右孩子,设置RTag为Thread,// 并把刚刚访问过结点的rchild指向当前结点,设为后继if (!pre->rchild) {pre->RTag = Thread;pre->rchild = p;}pre = p;InTreading(p->rchild);}
}void InOrderThreading(BiThrTree &Thrt, BiThrTree T) {//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点if (!(Thrt = (BiThrTree) malloc(sizeof(BiThrNode))))exit(0);//建立头结点Thrt->LTag = Link;Thrt->RTag = Thread;Thrt->rchild = Thrt;//右指针回指//若二叉树空,则左指针回指if (!T)Thrt->lchild = Thrt;else {Thrt->lchild = T;pre = Thrt;InTreading(T);//中序遍历进行中序线索化//最后一个结点线索化pre->rchild = Thrt;pre->RTag = Thread;Thrt->rchild = pre;}
}void PrintElement(TElemType e) {printf("%c", e);
}void InOrderTraverse_Thr(BiThrTree T) {//T指向头结点,头结点的左链lchild指向根结点//中序遍历二叉线索树T的非递归算法BiThrTree p;p = T->lchild;//p指向根结点while (p != T) {//空树或遍历结束时,p==Twhile (p->LTag == Link)p = p->lchild;if (!p->data)exit(0);elsePrintElement(p->data);//访问其左子树为空的结点while (p->RTag == Thread && p->rchild != T) {p = p->rchild;PrintElement(p->data);//访问后继结点}p = p->rchild;}
}

树、森林及二叉树的相互转换

· 树转换成二叉树

-加线,在所有兄弟结点之间加一条线。

-去线,对树中每个结点,只保留它与第一孩子结点的连线,

删除它与其他孩子结点之间的连线。

-层次调整,以树的根结点为轴心,将整棵树顺时针旋转

一定角度,使之结构层次分明。

1.第一步,在树中所有兄弟结点之间加一连线

2.第二步,对每个结点,除了保留与其长子的连线外,去掉该结点与其它孩子的连线。

· 森林转换二叉树

-先将森林中的每棵树变为二叉树。

-再将各二叉树的根结点视为兄弟从左至右连在一起,就这样形成一个二叉树。

把第一棵根结点为根结点,其他根结点连起来,作为它的右子树。

1.第一步,先将森林中的每棵树变为二叉树。

2.第二步,将各二叉树的根结点视为兄弟从左至右连在一起。

· 二叉树到树、森林的转换

    -二叉树转换为普通树是刚才的逆过程,步骤也就是反过来而已

-判断一棵二叉树能够转换成一棵树还是森林,那就是只要看这棵

二叉树的根结点有没有右子树,有的话就是森林,没有就是一棵树。

树与森林的遍历:(理解)

· 树的遍历分为两种方式:一种是先根遍历,另一种是后根遍历。

· 先根遍历:先访问树的根结点,然后再依次先根遍历根的每棵子树。

· 后根遍历:依次遍历每棵子树,然后再访问根结点。

· 先根遍历结果:ABEFCGDHIJ

· 后根遍历结果:EFBGCHIJDA

·森林的遍历也分为前序遍历和后序遍历,其实就是按照树的先根遍历和

后根遍历依次访问森林的每棵树。

· 有个 惊人的发现:树、森林前根(序)遍历和二叉树的前序遍历结果相同,

树、森林的后根(序)遍历和二叉树的中序遍历结果相同

· 于是我们可以找到对树和森林遍历这种复杂问题的简单解决方案。

赫夫曼树

· 结点的路径长度:

-从根结点到该结点的路径上的连接数

· 树的路径长度:

-树中每个叶子结点的路径长度之和

· 结点带权路径长度:

-结点的路径长度与结点权值的乘积

· 树的带权路径长度:

-WPL是树中所有叶子结点的带权路径长度之和

WPL值越小,说明构造出来的二叉树性能越优

赫夫曼树的构造过程

-选权值最小的两个结点构成一个二叉树,其双亲结点权值为两个结点权值之和。

-然后再选取剩下结点的权值最小的,与上一步的二叉树组合,构成新的二叉树,

如此重复,直到没有结点剩下,这棵二叉树便是赫夫曼树。

构造完成。

注意:为了使得到的哈夫曼树的结构尽量唯一,通常规定生成的哈夫曼树中每个结点的左子树

根结点的权小于等于右子树根结点的权。

赫夫曼编码

· 赫夫曼编码可以有效地压缩数据(通常可以节省20%~90%的空间,具体压缩率依赖于数据的特性)。

· 定长编码、变长编码、前缀码

-定长编码:类似于ASCII编码。

-变长编码:单个编码的长度不一致,可以根据整体出现频率来调节。

-前缀码:没有任何码字是其他码字的前缀。

·  赫夫曼树中没有度为1的结点(这类树又称为严格的二叉树),则一棵有n个叶子结点的赫夫曼树

共有2n-1个结点,可以存储在一个大小为2n-1的以为数组中。

· 由于在构成赫夫曼树之后,为求编码需从叶子结点出发走一条从叶子到根的路径;而为编码需

从根到叶子的路径。则对没个结点而言,既需知双亲的信息,又需知孩子结点的信息。

代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct {int weight;int parent, lchild, rchild;
} HTNode, *HuffmanTree;   //动态分配数组存储赫夫曼树
typedef char **HuffmanCode;//动态分配数组存储赫夫曼编码表
//这里可以理解成相当于许多字符串组成的数组void Select(HuffmanTree htree, int end, int &s1, int &s2) {//从数集中选取parent=0,weight最小的两个结点,其下标存入s1,s2int min1, min2;int i = 1;//找到第一个没有双亲的结点while (htree[i].parent != 0 && i <= end)i++;//作为一个参考的最小值,存入min1和s1min1 = htree[i].weight;s1 = i;//下个结点开始i++;//找到第二个没有双亲的结点,与前面那个作对比//较小的放min1和s1,较大的放min2和s2while (htree[i].parent != 0 && i <= end)i++;if (htree[i].weight < min1) {min2 = min1;s2 = s1;min1 = htree[i].weight;s1 = i;} else {min2 = htree[i].weight;s2 = i;}//遍历剩下无双亲的结点for (int j = i + 1; j <= end; j++) {if (htree[j].parent != 0)continue;//如果比min1小,min1,s1的数据移到min2,s2//并把当前结点的值赋给min1,结点序号给s1if (htree[j].weight < min1) {min2 = min1;min1 = htree[j].weight;s2 = s1;s1 = j;} else if (htree[j].weight >= min1 && htree[j].weight < min2) {//如果比min1大且比min2小,//则把当前结点值赋给min2,序号给s2min2 = htree[j].weight;s2 = j;}}
}void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n) {//w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼树编码HCHuffmanTree p;int i, s1, s2, start, c, f;if (n <= 1)return;int m = 2 * n - 1;HT = (HuffmanTree) malloc((m + 1) * sizeof(HTNode));//0号单元不用//注意,第一个结点为空//每个结点赋初值//n个叶子结点for (p = HT+1, i = 1; i <= n; ++i, ++p, ++w)*p = {*w, 0, 0, 0};//m-n个终端结点for (i; i <= m; ++i, ++p)*p = {0, 0, 0, 0};for (i = n + 1; i <= m; ++i) {//在HT[1...i-1]选择parent为0且weight最小的两个结点,其序号分别为 s1和s2//组合好后又成为一个新的可选结点,故[1...i-1]Select(HT, i - 1, s1, s2);//最小两个结点的双亲序号为当前iHT[s1].parent = i;HT[s2].parent = i;//当前i结点左右孩子序号分别是s1,s2HT[i].lchild = s1;HT[i].rchild = s2;//权重为两孩子之和HT[i].weight = HT[s1].weight + HT[s2].weight;}//---从叶子到根逆向求没个字符的赫夫曼编码---//分配n+1个字符编码的头指针向量//0号位不存放数据HC = (HuffmanCode) malloc((n + 1) * sizeof(char *));//分配求编码的工作空间char *cd = (char *) malloc(n * sizeof(char));//最后一个字符为结束符cd[n - 1] = '\0';//逐个字符求赫夫曼编码for (i = 1; i <= n; ++i) {start = n - 1;//编码结束符位置for (c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent){//从叶子到根逆向求编码if (HT[f].lchild == c)cd[--start] = '0';elsecd[--start] = '1';}//为第i个字符分配空间HC[i] = (char *) malloc((n - start) * sizeof(char));//将遍历得到的编码串复制到HC[i]strcpy(HC[i], &cd[start]);}free(cd);
}void print_huffman_tree(HuffmanTree htree, int n) {printf("Huffman tree:\n");int m = 2 * n - 1;for (int i = 1; i < m; ++i) {printf("node_%d, weight = %d, parent = %d, left = %d, right = %d\n",i, htree[i].weight, htree[i].parent, htree[i].lchild, htree[i].rchild);}
}void print_all_huffman_code(HuffmanCode HC, int n) {printf("Huffman code:\n");for (int i = 1; i <= n; ++i) {printf("%d code = %s\n", i, HC[i]);}
}int main() {int w[5] = {2, 8, 7, 6, 5};int n = 5;HuffmanTree HT;HuffmanCode HC;HuffmanCoding(HT, HC, w, n);print_huffman_tree(HT, n);print_all_huffman_code(HC, n);return 0;
}

数据结构(C语言版 严蔚敏著)——树相关推荐

  1. 数据结构(C语言版)严蔚敏(树、二叉树的相关概念笔记)

    数据结构(C语言版)严蔚敏(树的相关概念笔记) 1. 树中一个节点的孩子个数称为该节点的度,树中节点的最大度数称为树的度: 2. 度大于0的节点称为[分支节点](非终端节点),度为0的节点称为[叶子节 ...

  2. 数据结构(C语言版)严蔚敏---图的操作的相关代码

    1. 将邻接表转换成邻接矩阵 main.cpp void Convert(ALGraph G,MGraph &M){M.vexnum = G.vexnum;M.arcnum = G.arcnu ...

  3. c语言实现bf算法的定位函数,数据结构c语言版严蔚敏清华大学出版社第四章串.ppt...

    数据结构c语言版严蔚敏清华大学出版社第四章串 模式匹配(定位) 设有主串S和子串T(将S称为目标串,将T称为模式串),在主串S中,从位置start开始查找,如若在主串S中找到一个与子串T相等的子串,则 ...

  4. 数据结构(C语言版)严蔚敏(字符串的模式匹配算法--KMP算法)

    数据结构(C语言版)严蔚敏(字符串的模式匹配算法–KMP算法) 1.暴力匹配算法 // 暴力匹配算法 int Index2(SString S,SString T) {// S是主串,T是子串int ...

  5. 数据结构c语言版严蔚敏 顺序表

    说来惭愧由于贪玩,数据结构挂科了,现在重新学一遍数据结构,用博客督促一下自己,希望各位同学引以为戒,贪玩一时爽,痛苦永留存. 本文主要以严老师的数据结构书为主. 结构类型 listsize代表这个顺序 ...

  6. 数据结构(C语言版)严蔚敏->二叉树(链式存储结构)的构造及其几种遍历方式(先序、中序、后序、层次)和线索二叉树

    二叉树每个节点至多只有两棵子树(即二叉树中不存在度大于2的节点),并且二叉树的子树有左右之分,其次序不能任意颠倒. 1. 二叉树 二叉树一般采用链式存储结构,用链表节点来存储二叉树中每个节点.在二叉树 ...

  7. 数据结构(C语言版)严蔚敏->排序

    排序 1. 插入排序 1.1 直接插入排序 1.2 折半插入排序 1.3 希尔排序(Shell Sort) 2.交换排序 2.1 冒泡排序 2.2 快速排序 3. 选择排序 3.1 简单选择排序 3. ...

  8. 数据结构(C语言版 严蔚敏 编著)课后习题答案

    转自 https://blog.csdn.net/Bamboo_shui/article/details/72433523    (原文没第八章答案) 数据结构(C语言版 第2版)课后习题答案 严蔚敏 ...

  9. 《数据结构》C语言版 严蔚敏版本 学习笔记

    笔者的话: 严蔚敏版本的这本<数据结构>脉络清晰,第二到第六的章节围绕绪论展开,而书本封面处也有本书结构框图,希望读者在学习的同时能够对照结构框图,搭建知识框架. 第一章 绪论 早期计算机 ...

最新文章

  1. java jvm对象_【Java】JVM
  2. 计算机bq,BQ24721部分翻译
  3. C语言——数组、函数、指针
  4. 阿里云喻义:十年牧码,从码农走向工程师的进化之路
  5. 服务器克隆机网络端口排错
  6. 可以学习的国外课件链接地址(自己收集)
  7. 海信新机F30S即将发布:搭载紫光展锐虎贲T310处理器
  8. centos mysql 同步时间_centos:mysql主从同步配置(2018)
  9. Hibernate---延迟加载和OpenSessionInView
  10. atitit。mssql sql server 转换mysql 及 分页sql ast的搭建
  11. Linux系统封装及配置
  12. 欧阳娜娜从阿里跳槽网易:阿里P8堪称教科书级别的面试现场!最后一个问题亮了...
  13. 《wifi加密破解论文》翻译介绍-wifi不再安全
  14. 给定一个无重复元素的数组 candidates 和一个目标数 target .
  15. 密码应用安全性评估实施要点之三密钥管理要求与实现要点
  16. python开方 运算符_[转载] Python中的算数运算符
  17. 华为防火墙配置基于源地址的策略路由
  18. 认清GPU的流处理器作用
  19. U盘插电脑有提示音但不显示盘符怎么办?
  20. 解决微软商店的游戏服务应用更新失败问题

热门文章

  1. MySQL 为日期增加一个时间间隔
  2. 敏捷仪式感之:敏捷宣传栏
  3. 台积电全球员工薪酬中位数约46万,CEO约899万;苹果上调日本的 iPhone 售价 ;Vim 9.0 发布|极客头条...
  4. Kafka3.2.0 + kraft集群安装部署说明
  5. 设置无线路由器与有线网络在同一网段
  6. 怎么翻译图片上的英文?图片翻译英文方法分享。
  7. PDF工具Adobe Arcrobat Pro DC下载安装教程
  8. C++三角定位法求两圆交点坐标
  9. 圣诞树拼图游戏unity制作
  10. vlookup(精确查找、区间查找、反向查找、多条件查找)