1.树知识体系搭建

2.树的基础知识

2.1 关于树结构

树形结构是非常重要的非线性结构,是以分支关系定义的一对多的层次结构。
树是n(n≥0)个结点的有限集。当n=0时,称为空树。在任意一棵非空树中应满足:
a.有且仅有一个特定的称为根的结点。
b.当n>1时,其余结点可分为m(m>0)个互不相交的有限集T,T2,…,Tm,其中每个集
合本身又是一棵树,并且称为根的子树。

树结构具有以下性质:

  • 树的根结点没有前驱,除根结点外的所有结点有且只有一个前驱。
  • 树中所有结点可以有零个或多个后继。

2.2 树的相关概念

结点:一个数据元素及其若干指向其子树的分支。
结点的度:结点所拥有的子树的棵数称为结点的度。
树的度:树中结点的度的最大值称为树的度。
叶子结点:树中度为0(向下没有分支)的结点称为叶子结点(或终端结点)。
非叶子结点:树中度不为0(问下有分支)的结点称为非叶子结点(或非终端结点或分支结点)。
除了根结点,分支结点也称为内部结点。
子结点:一个结点的子树的根称为该结点的孩子结点或子结点。
双亲结点或父节点:与子结点对应,子树的根。
兄弟结点:同一双亲结点的所有子结点互称为兄弟结点。
层次:规定树中根结点的层次为1,其众结点的层次等于其双亲结点的层次加1。
堂兄弟结点:在同一层上,但是双亲不同的所有结点互称为堂兄弟结点。
层次路径:从根结点开始,到达某结点p所经过的所有结点称为结点p的层次路径(有且只有一条)。
祖先结点:结点p的层次路径上的所有结点(p除外)称为p的祖先。
子孙结点:以某结点为根的子树中的任意结点称为该结点的子孙结点。
树的深度: 树中结点的最大层次值,又称为树的高度。
分支数=孩子数=度

2.3 树的主要性质

性质1:树中的结点个数等于所有结点的度之和加1。
性质2:对m度树,定义叶子结点个数为 n 0 n_0 n0​,度为1的结点个数为 n 1 n_1 n1​,… ,度为m的结点个数为 n m n_m nm​,
于是有 n 0 = n 2 + 2 ∗ n 3 + 3 ∗ n 4 + … + ( m − 1 ) ∗ n m + 1 n_0=n_2+2*n_3+3*n_4+…+(m-1)*n_m+1 n0​=n2​+2∗n3​+3∗n4​+…+(m−1)∗nm​+1
性质3:在非空m度树中,第i层上至多有 m i − 1 m^{i -1} mi−1个结点(i≥1)。
性质4:高度为h的m(m>1)度树,最多有 m h − 1 m − 1 \frac{m^{h}-1}{m-1} m−1mh−1​个结点。
性质5:具有n个结点的m度树的最小高度是 log ⁡ m [ n ∗ ( m − 1 ) + 1 ] \log_m[n * (m -1) +1] logm​[n∗(m−1)+1]

2.4 树的表示方法

双亲表示法
孩子链表示法
孩子兄弟表示法

3.二叉树

3.1 定义及主要特性

二叉树的定义只需要把树的定义中m个分支改成最多两个分支就可以了。

3.1.1 二叉树的注意事项
  • a.二叉树分为左、右子树,那么就意味着二叉树是有序树,它和二度树是不一样的。二度树可能不是有序树;但是二叉树一定是有序树。
  • b.二叉树最多有两个分支,也就是二叉树的度最多是2,但是并不是说每个结点的度都是2。
3.1.2 二叉树的性质

性质1:树中的结点个数等于所有结点的度之和加1。
性质2:对任意一棵二叉树,定义叶子结点个数为 n 0 n_0 n0​,度为2的结点个数为 n 2 n_2 n2​, n 0 = n 2 + 1 n_0=n_2+1 n0​=n2​+1
性质3:在非空二叉树中,第i层上至多有 2 i − 1 2^{i -1} 2i−1个结点(i≥1)。
性质4:高度为k的二叉树,最多有 2 k − 1 {2^{k}-1} 2k−1个结点(k≥1)。
性质5:具有n个结点的二叉树的最小高度是 log ⁡ 2 ( n + 1 ) \log_2(n +1) log2​(n+1)

3.1.3 二叉树的分类

满二叉树、完全二叉树、二叉排序树、平衡二叉树、折半树
、堆。

  • 满二叉树:满、一棵深度为k且有 2 k − 1 {2^{k}-1} 2k−1个结点的二义树称为满二义树。
  • 完全二叉树:如果深度为k,由n个结点构成的二叉树,当且仅当其每个结点都与深度为k的满二叉树中编号从1到n的结点一一对应时,该二叉树称为完全二叉树。(对应位置、对应编号、不跳号)
3.1.4 满二叉树特点
  • 每层上的结点数总是最大结点数。
  • 所有的非叶子结点都有左、右子树。
  • 对满二叉树的结点进行连续编号,若规定从根结点1开始,则按“自上而下、白左至右”的原则进行。
3.1.5 完全二叉树的性质
  • 性质1:在非空一叉树,第i层上至多有 2 k − 1 2^{k-1} 2k−1个结点(i≥1)。

  • 性质2:深度为k的二叉树至多有 2 k − 1 2^{k}-1 2k−1个结点(k≥1).

  • 性质3:对任何一棵二叉树,若其叶子结点数为n,度为2的结点数为 n 2 n_2 n2​,则 n 0 = n 2 十 1 n_0=n_2十1 n0​=n2​十1

  • 性质4:树中的结点个数等于所有结点的度之和加1

  • 性质5:深度为k的满二叉树中编号从1到n的前n个结点构成了一棵深度为k的完全二叉树,其中 2 k − 1 ≤ n ≤ 2 k − 1 2^{k-1}\le n \le2^k-1 2k−1≤n≤2k−1

  • 性质6:n个结点的完全二义树深度为 ( l o g 2 n ) + 1 (log_2n)+1 (log2​n)+1或 l o g 2 ( n + 1 ) log_2(n+1) log2​(n+1)。

  • 性质7:若完全二叉树的深度为k,则所有的叶子结点都出现在第k层或第k-1层。

  • 性质8:对于任一结点,若其右子树的最大层次为1,则其左子树的最大层次为1或2。

  • 性质9:若对一棵有n个结点的完全二叉树(深度为 ( l o g 2 n ) + 1 (log_2n)+1 (log2​n)+1)的结点按层(从第1层到第 ( l o g 2 n ) + 1 (log_2n)+1 (log2​n)+1层)序自左至右进行编号,则对于编号为1( 1 ≤ i ≤ n 1\le i \le n 1≤i≤n)的结点,有以下情形:
    ①若i=1,则结点i是二叉树的根,无双亲结点;否则,若i>1,则其双亲结点编号是[i/2」
    ②若2i>n,则结点i为叶子结点,无左孩子:否则,其左孩子结点编号是2i.
    ③若2i+1>n,则结点i无右孩子;否则,其右孩子结点编号是2i+1。

  • 性质10:对于一棵完全二叉树,度为1的结点个数是1或0。

3.2 二叉树的存储

3.2.1 顺序结构存储

二叉树的顺序存储就是按照每个结点的编号作为数组下标存储到数组中;如果不满足完全二叉树,我们以通过补空标志,构建一棵完全二叉树。
在最坏的情况下,一个深度为k且只有k个结点的单支树需要长度为 2 k − 1 2^{k-1} 2k−1的一维数组。此时是一棵单右支树。一般只有完全二叉树才采用顺序结构进行存储,一般的二叉树不适用于顺序结构。

#define MAX_SIZE 100
typedef int sqbitree[MAX_SIZE];
3.2.2 链式结构存储

因为二叉树有左、右两个子树,所以二叉树的链式结构的每个结点有3个域:一个数据域,两个分别指向左、右子结点的指针域。

3.3 二叉树的遍历

二叉树的遍历分为:先序遍历、中序遍历、后序遍历和层次遍历。
先序遍历、中序遍历、后序遍历需要使用到栈,而层次遍历需要用到队列。无论是哪种遍历,在遍历过程中,叶子结点的相对顺序是不变的。

3.3.1 基本概念

访问是指对结点做某种处理,如输出信息、修改结点的值,我们把访问结点的操作称为遍历,遍历二叉树是指按指定的规律对二叉树中的每个结点访问一次且仅访问一次。

若以L、D、R分别表示遍历左子树、遍历根节点和遍历右子树,则会有以下6种遍历方案:LDR、LRD、DLR、DRL、RLD、RDL。如果事先约定先左后右,则只有以下三种情况:DLR——先序(根)遍历、LDR——中序(根)遍历、LRD——后序(根)遍历。

3.3.2 先序遍历

先序遍历就是从二叉树的根结点出发,当第一次到达结点时就输出结点数据,按照先向左再向右的方向访问。若二叉树为空,则遍历结束。否则有以下情形:
a.访问根结点。
b.先序遍历左子树(递归调用本算法)。
c.先序遍历子树(涕归调用本算法)。

若采用递归进行遍历,则会调用系统栈进行遍历,具体代码如下:

//二叉树定义部分:
#include<stdio.h>
#include<stdbool.h>
typedef int ElementType;
typedef struct BTNode{ElementType data;struct BTNode * Lchild, *Rchild;
}BTNode;
void PreorderTraverse(BTNode * T){//先序遍历,递归写法//如果为空,则访问根结点if(T == NULL) return;printf("%d\n", T->data);PreorderTraverse(T->Lchild);PreorderTraverse(T->Rchild);
}

若采用用户栈,可以借助以下代码:

//定义需要用的类型及函数
#include<stdio.h>
#include<stdbool.h>
#define MAX_SIZE 100
typedef int ElementType;
typedef struct BTNode{ElementType data;struct BTNode * Lchild, *Rchild;
}BTNode;
typedef struct Stack{//定义栈//定义一个存放二叉树指针的数组BTNode * data[MAX_SIZE];int top;
}SqStack;void Init_stack(SqStack * S){S->top = 0;
}int isEmpty(SqStack * S){if(S->top == 0) return 1;else return 0;
}bool push(SqStack * S, BTNode * node){if (S->top == MAX_SIZE) return false;S->data[S->top] = node;S->top++;return true;
}BTNode * pop(SqStack * S){//出栈if (S->top == 0) return NULL;S->top--;return S->data[S->top];
}
void PreorderTraverse_user(BTNode * root){//二叉树遍历,调用用户栈//用来暂存结点的栈//BTNode * stack[100];SqStack * stack;Init_stack(stack);// 新建一个工作结点,并指向根结点BTNode * node = root;// 当遍历到最后一个结点,若左右子树都为空,且栈也为空,则跳出循环。//while (node != NULL || !stack.isEmpty()){while (node != NULL || !isEmpty(stack)){while(node != NULL){printf("%d\n", node->data);//暂存该结点//stack.push(node);push(stack, node);node = node->Lchild;}//if (!stack.isEmpty()){if (!isEmpty(stack)){//左子树为空,再取出该元素,并获取其右子树//node = stack.pop();node = pop(stack);node = node->Rchild;}}
}
3.3.3 中序遍历

中序遍历就是从二叉树的根结点出发,当第二次到达结点时输出结点数据,按照先向左再向右的方向访问。算法的递归定义是:若二叉树为空,则遍历结束:否则有以下情形:
a.中序遍历左子树(递归调用本算法)。
b.访回根结点。
c.中序遍历右子树(递归调用本算法)。
调用递归方法实现代码如下:

void InorderTraverse(BTNode * T){// 中序遍历if (T == NULL) return;InorderTraverse(T->Lchild);printf("%d", T->data);InorderTraverse(T->Rchild);
}

调用用户栈,自定义方法如下:

void midorderTraversal(BTNode * root){SqStack * stack;Init_stack(stack);BTNode * node = root;while(node != NULL || !isEmpty(stack)){while(node != NULL){push(stack, node);node = node->Lchild;}if (!isEmpty(stack)){node = pop(stack);printf("%d", node->data);node = node ->Rchild;}}
}
3.3.4 后序遍历

后序遍历就是从二叉树的根结点出发,当第三次到达结点时就输出结点数据,按照先向左再向右的方向访问。算法的递归定义是:若二叉树为空,则遍历结束;否则有以下情形:
a.后序遍历左子树(递归调用本算法)。
b.后序遍右子树(递归调用木算法)。
c.访回根结点。
若使用系统栈,采用递归方法如下:

void postTraverse(BTNode * T){//后续遍历if (T == NULL) return;postTraverse(T->Lchild);postTraverse(T->Rchild);printf("%d\n", T->data);
}

若采用用户栈,自定义方法如下:

void postTraversal(BTNode * root){SqStack * stack;BTNode * node = root;BTNode * last = root;while(node != NULL || !isEmpty(stack)){while (node != NULL){push(stack, node);node =node->Lchild;}// 查看当前栈顶元素//如果其右子树为空,或者右子树已经访问,则输出该结点的值if (node->Rchild == NULL || node->Rchild == last){printf("%d\n", node->data);pop(stack);last = node;node = NULL;}else{node = node->Rchild;}}
}
3.3.5 层次遍历

层次遍历二叉树,是从根结点开始遍历,按层次次序“自上而下,从左至右”访问树中的各结点。为保证是按层次遍历,必须设置一个队列,初始化时为空。设T是指向根结点的指针变量,层次遍历非递归法是:若二叉树为空,则返回;否则,令p=T,p入队。
a.队首元素出队到p。
b.访问p所指向的结点。
c.将p所指向的结点的左、右子结点依次入队,直到队空为止。
实现代码如下:

void leverTraverse(BTNode * T){// 定义一个队列来存储结点BTNode * Queue[MAX_SIZE];BTNode * p = T;int front = rear = 0;// 当结点部位空时,开始进出队列if(p != NULL){Queue[rear++] = p;while(front < rear){//当队列不为空,进行输出和访问。p = Queue[front++];printf("%d", p->data);//有左结点,就将左节点放到队列中if (p->Lchild != NULL)Queue[front++] = p->Lchild;if (p->Rchild != NULL)Queue[front++] = p->Rchild;}}
}
3.3.6 二叉树的生成

以下三种组合可以唯一确定一棵二叉树:

  • 先序遍历 + 中序遍历
  • 后序遍历 + 中序遍历
  • 层次遍历 + 中序遍历

3.4 线索二叉树

在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化。

3.4.1 线索二叉树的标记方法
  • 若结点有左孩子,则Lchild指向其左孩子:否则,指向其直接前驱。
  • 若结点有右孩子,则Rchild指向其右孩子;否则,指向其直接后继。
    线索二叉树的结构如下:
左孩子或直接前驱 是否无左孩子 数据 是否无右孩子 右孩子或直接后继
Lchild Ltag data Rtag Rchild

以Ltag为例,标记方法如下:

  • Ltag标记为0,Lchild指向结点的左孩子
  • Ltag标记为1,Lchild指向结点的直接前驱
3.4.2 线索二叉树的构造

先写出遍历序列,然后根据有无子树添加指向左、右子树的指针或指向直接前驱、直接后继的线索。
以下为线索二叉树的构建例子:

4. 树、森林

4.1 树和二叉树的转换

4.1.1 将树转为二叉树

对于一般的树,可以方便地转换成一棵唯一的二叉树与之对应。其详细步骤如下(孩子兄弟表示法):

  • ①加虚线。在树的每层按从左至右的顺序在兄弟结点之间加虚线相连。
  • ②去连线。除最左的第一个子结点之外,父结点与所有其他子结点的连线都去掉。
  • ③旋转。将树顺时针旋转45度,原有的实线左斜。
  • ④整型。将旋转后树中的所有虚线改为实线,并向右斜。

此处举一例子,如下:

4.1.2 二叉树转为树

二叉树转为树,步骤如下:

  • ①加虚线。若某结点i是其父结点的左子树的根结点,则将该结点ⅰ的右孩子结点及沿右孩子链搜索到的所有的右孩子结点,与i结点的父结点之间加虚线相连。
  • ②去连线。去掉二叉树中所有父结点与其右子结点之间的连线。
  • ③规整化。将图中各结点按层次排列且将所有的虚线变成实线。逆时针转动45度。

举一例子,如下:

4.2 树的存储结构

4.3 森林与二叉树的转换

4.3.1 森林转为二叉树

森林转换成二叉树的转换步骤如下:

  • ①将F={T,T2,…,T}中的每棵树转换成二叉树。
  • ②按给出的森林中树的次序,从最后一棵二叉树开始,每棵二叉树作为前一棵二叉树的根结点的右子树,依次类推,则第一棵树的根结点就是转换后生成的二叉树的根结点。

以下是森林转为树的案例:

4.3.2 二叉树转为森林

二叉树转为森林的步骤如下:
①去连线。将二叉树的根结点与其右子结点,以及沿右子结点链方向的所有右子结点的连线全部去掉,得到若干棵孤立的二叉树,每棵树就是原来森林中的树依次对应的二叉树。
②二叉树的还原。将各棵孤立的二叉树按二叉树还原为树的方法还原成一般的树。
二叉树转为森林的例子如下:

4.4 树和森林的遍历

树的遍历有两种:先序遍历和后序遍历。

  • 先序遍历:先访问根结点,然后依次先序遍历完每棵子树。树的先序遍历与将树转为二叉树后,对二叉树的先序遍历相同。
  • 后序遍历:先依次后序遍历完每棵子树,然后访问根结点。树的后序遍历与将树转换成二叉树后,对二叉树的中序遍历相同。

5. 树与二叉树的应用

5.1 二叉排序树

5.2 平衡二叉树

5.3 哈夫曼树和哈弗曼编码

5.3.1 相关概念
  • 结点路径:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径。
  • 路径长度:结点路径上的分支数目称为路径长度。
  • 树的路径长度:从树根到每个结点的路径长度之和。
  • 结点的带权路径长度:从该结点到树的根结点之间的路径长度与结点的权(值)的乘积。其中,权(值)是各种开销、代价、频度等的抽象称呼。
  • 树的带权路径长度:树中所有叶子结点的带权路径长度(WTL)之和,记作
    W P L = ω 1 ι 1 + ω 2 ι 2 + . . . + ω n ι n = ∑ i = 1 n ω i ι i WPL = \omega_1\iota_1+\omega_2\iota_2+...+\omega_n\iota_n=\sum_{i=1}^{n}\omega_i\iota_i WPL=ω1​ι1​+ω2​ι2​+...+ωn​ιn​=i=1∑n​ωi​ιi​
  • 哈夫曼(Huffman)树:具有n个叶子结点(每个结点的权值为 ω 1 \omega_1 ω1​)的二叉树不止一棵。但在所有的这些二叉树中,必定存在一棵WPL值最小的树,称这棵树为哈夫曼树(或称为最优树)。

以下为计算WPL的例子:

5.3.2 哈夫曼树的构建

构建要点:需要让编码长的路径长度长一些,编码短的路径长度短一些即可。
给定n个权值分别为 w 1 w_1 w1​, w 2 w_2 w2​,…, w n w_n wn​的结点,构造哈夫曼树的算法描述如下:

  1. 将这n个结点分别作为n棵仅含一个结点的二叉树,构成森林F。
  2. 构造一个新结点,从F中选取两棵根结点权值最小的树作为新结点的左、右子树,并且将新结点的权值置为左、右子树上根结点的权值之和。
  3. 从F中删除刚才选出的两棵树,同时将新得到的树加入F中。
  4. 重复步骤2和3,直至F中只剩下一棵树为止。

例子:
如将w={8,3,4,6,5,5}构造成哈夫曼树,步骤图如下:


其WPL值如下:

W P L = 6 ∗ 2 + 3 ∗ 3 + 4 ∗ 3 + 8 ∗ 2 + 5 ∗ 3 + 5 ∗ 3 = 79 WPL=6*2+3*3+4*3+8*2+5*3+5*3=79 WPL=6∗2+3∗3+4∗3+8∗2+5∗3+5∗3=79

5.3.3 哈夫曼编码

若没有一个编码是另一个编码的前缀,则称这样的编码为前缀编码。
由哈夫曼树得到哈夫曼编码是很自然的过程。首先,将每个出现的字符当作一个独立的结点,其权值为它出现的频度(或次数),构造出对应的哈夫曼树。显然,所有字符结点都出现在叶结点中。我们可将字符的编码解释为从根至该字符的路径上边标记的序列,其中边标记为0表示“转向左孩子”,标记为1表示“转向右孩子”。

如何判断是不是哈夫曼编码?

  • 方法1: 根据其是否符合前缀编码的定义
  • 方法2:将哈夫曼树绘制出来,看是否符合
5.3.4 哈夫曼树的特点
  • 哈夫曼树只有0度结点和2度结点。
  • 哈夫曼树的WPL值最小。
  • 哈夫曼树不唯一,因为哈夫曼树的左、右子树可以交换,但是W值唯一。
  • 哈夫曼树本质上不属于二叉树,但通常我们认为哈夫曼树是二叉树。
  • 哈夫曼树的上层结点的权值不小于下层结点的权值。
  • 哈夫曼编码只讨论叶子的编码。

5.4 红黑树

5.5 并查集及其应用

并查集是一种非常精巧且实用的数据结构,它主要用于处理一些不相交集合的合并及查询向题。常见的用途有求连通子图、求最小生成树的Kruskal算法和求最近公共祖先。
在使用并查集时,首先会存任一组不相交的动态集合S={S1,s2,…,Sn},一般会使用一个整数表示集合中的一个元素。

并查集是一种简单的集合表示,它支持以下3种操作:

  1. Initial(S):将集合S中的每个元素都初始化为只有一个单元素的子集合。
  2. Union(S,Root1,Root2):把集合S中的子集合Root2并入子集合Root1。要求Root1和Root2互不相交,否则不执行合并。
  3. Find(S,x):查找集合S中单元素x所在的子集合,并返回该子集合的根结点。

通常用树(森林)的双亲表示作为并查集的存储结构,每个子集合以一棵树表示。所有表示子集合的树,构成表示全集合的森林,存放在双亲表示数组内。通常用数组元素的下标代表元素名,用根结点的下标代表子集合名,根结点的双亲结点为负数。

一篇文章学懂数据结构中的树相关推荐

  1. 二叉搜索树的删除操作可以交换吗_一文看懂数据结构中的树

    通常在开始学编程的时候,你会接触一些常用数据结构.到最后一般会学到哈希表.对于修读计算机科学学位的朋友,你通常要上专门的数据结构课,从了解有关链表.队列和栈的各种知识.这些统称为线性数据结构,因为依逻 ...

  2. 一篇文章学懂Shell脚本

    Shell脚本,就是利用Shell的命令解释的功能,对一个纯文本的文件进行解析,然后执行这些功能,也可以说Shell脚本就是一系列命令的集合. Shell可以直接使用在win/Unix/Linux上面 ...

  3. 一篇文章学懂Shell脚本,最简明的教程在这里

    Shell脚本,就是利用Shell的命令解释的功能,对一个纯文本的文件进行解析,然后执行这些功能,也可以说Shell脚本就是一系列命令的集合. Shell可以直接使用在win/Unix/Linux上面 ...

  4. 六个问题搞懂数据结构中的树的分支

    几个问题:树按如下编号 1.寻找父节点:一个完全k叉树,如果一个节点的编号是i,求它的父节点的编号(如果有父节点的话) 先来看答案 如果是一个结点的孩子结点中的最大结点,那么最大节点编号减去根节点编号 ...

  5. 一篇文章搞懂数据埋点与数据同步

    目录 (1)到底什么是埋点 (2)企业数据埋点方案 (3)企业数据同步方案 (4)数据漂移场景及处理方案 (1)到底什么是埋点 埋点的概念: 埋点是数据采集中的一个统称,通常也叫做事件追踪(Event ...

  6. 【译】数据结构中关于树的一切(java版)

    你每天都那么努力,忍受了那么多的寂寞和痛苦.可我也没见你有多优秀. https://user-gold-cdn.xitu.io/2018/4/17/162d1b4c1dd95fa3?w=1080&am ...

  7. 一篇文章看懂:量化交易

    什么是量化交易? 度娘官方版 - 理论这么说 量化交易是指以先进的数学模型替代人为的主观判断,利用计算机技术从庞大的历史数据中海选能带来超额收益的多种"大概率"事件以制定策略,极大 ...

  8. 计算机论文章节构成,一篇文章弄懂电脑的组成

    原标题:一篇文章弄懂电脑的组成 来源:转载于网络:学电脑知识http://www.pc280.com 今天为大家全面介绍电脑的组成,看完这个你一定再也不会对这个铁盒子产生畏惧,一定让你理解,让你懂! ...

  9. 一篇文章读懂MySQL的各种联合查询

    一篇文章读懂MySQL的各种联合查询 联合查询是指将两个或两个以上的表的数据根据一定的条件合并在一起! 联合查询主要有以下几种方式: 全连接:将一张表的数据与另外一张表的数据彼此交叉联合查询出来 举例 ...

最新文章

  1. java如何读取word的占位符_java利用xml导出word(占位符替换)
  2. Nginx +uwsgi+django配置
  3. Exchange2007 申请安装证书
  4. 方立勋_30天掌握JavaWeb_JavaBean、mvc开发模式、el表达式、jstl标签
  5. 深度召回算法在字节跳动推荐系统的应用实践
  6. 对权值线段树剪枝的误解--以HDU6703为例
  7. MSN网页上点击连接
  8. 在ArcGIS软件中导入数据图标题层不显示的问题
  9. windows 打补丁转载)
  10. 信道估计算法matlab代码汇总
  11. Redis Client 之 Jedis与Lettuce
  12. js实现GIF图片的分解和合成
  13. 安装炫酷桌面himawaripy实施卫星地图
  14. 小米投资美的布局智能家居 董明珠呛声:两个骗子
  15. HTML5之10 __使用 Canvas API创建 热点图
  16. 微信小程序官方组件展示之基础内容icon源码
  17. 【SpringCloud】ZuulFilter过滤器
  18. 【CoderSay】Code For Better 谷歌开发者之声 - 相遇2022GoogleSummit
  19. android实习报告,基于Android的毕业实习报告.doc
  20. java中文括号转英文

热门文章

  1. unity spine动画播放隐藏后马上显示播放抽搐的bug
  2. 2021年制冷与空调设备运行操作最新解析及制冷与空调设备运行操作新版试题
  3. 对受控组件和非受控组件的理解,以及应用场景?
  4. 存储税码和税率的表SAP
  5. Python socket模块
  6. WIN10快捷方式小箭头变成白色图标的修复方法
  7. 电脑如何恢复出厂设置
  8. ESP8266 TCP客户端代码(自动连接,断开识别)
  9. 奥本大学计算机科学硕士,2020年奥本大学硕士读几年
  10. 模糊熵(FE)计算的C++ 实现,及参考MATLAB代码