【数据结构】——二叉树的基础知识

数概念及结构

数的分类

二叉树、多叉树

数的概念

树是一种非线性的数据结构,它是由n(n>=0)个有限节点组成一个具有层次关系的集合。把它叫做树的原因是它看起来像一颗倒挂的树,也就是说它是跟朝上,而叶朝下的。

  • 有一个特殊的节点,称为根节点,这个节点没有前驱节点。
  • 除根节点外,其余节点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1<=i<=m)又是一颗结构与树类似的子树。每颗子树的根节点有且只有一个前驱,可以有0个或多个后继节点。
  • 数是递归定义的。
  • 子树是不相交的;
    什么是递归:
    大问题->类似子问题->类似子问题

数的相关概念

结点的度: 一个结点含有的子树的个数称为该结点的度。
叶结点或终端结点:度为0的结点。
非终端结点或分支结点:度不为0的结点。
双亲结点或父节点:若一个结点含有子结点,则这个结点称为其子结点。
孩子节点或父节点:一个节点含有子树的根的节点称为该节点的子节点。
兄弟节点:具有相同父节点的节点称为兄弟节点。
树的度:一个树中最大的节点的度称为树的度。
节点的层次:从跟开始定义起,根为第1层,根的子节点为第二层。
树的高度或深度:树中节点的最大层次。
堂兄弟节点:双亲在同一层次的节点互为堂兄弟。
节点的祖先:从根到该节点所经分支上的所有节点。
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
森林:由m(m>0)颗互不相交的树的集合称为森林。

数的高度一般都是从1开始,从0开始也可以。
扩展:
数组下标为什么要从0开始,因为这符合偏移量。
当前元素到第一个元素的偏移量,第一个元素的下标自然就是0,第二个元素的下标为1,第n个元素的下标为n-1。
并查集里面就是多棵树。

数的存储

树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,既要保存值域,也要保存节点和节点之间的关系,实际中树有很多的表示方式如:双亲表示法、孩子表示法、孩子双亲表示法以及孩子兄弟表示法等。我们这里简单的了解其中最常见的孩子兄弟表示法

struct TreeNode
{int val;struct TreeNode* firstchild;struct TreeNode*nextbrother;
}

数在实际中的运用(表示文件系统的目录结构)

image.png
文件系统就是一个树形结构。

还有一种双亲表示法:只存储双亲的下标或指针。
两个结点在不在同一棵树,如何判断?
找根,根相同就是在同一棵树。

二叉树概念及结构

概念

一颗二叉树是结点得一个有限集合,该集合:
1、或者为空
2、由一个根结点加上两颗别称为左子树和右子树得二叉树组成。
注意:
1、二叉树最多两个孩子。
2、二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树。
注意:
空树、只有根结点、只有左子树、只有右子树、左右子树均存在。

特殊的二叉树

满二叉树

每一层都是2^(i-1)个结点,每一层都是满的就是满二叉树。
高度为h的满二叉树有多少个节点:
F(h)=20+21+…+2(h-2)+2^(h-1)
使用错位相减法可以得到下面的结果
F(h)=2^h-1
image.png

完全二叉树

假设他的高度是h,前h-1层是满的,最后一层不一定满,从左到右是连续的。
image.png

二叉树的性质

1、若规定根节点的层数为1,则一颗非空二叉树的第i层上最多有2^(i-1)个节点。
2、若规定根节点的层数为1,则深度为h的二叉树的最大节点数是2^k-1.
3、在任何二叉树中,度为0的叶子节点永远比度为2的多一个,只有一个节点时 n0=n2+1。
完全二叉树特点:
度为1的节点只有1个或者0个。如果节点的个数是偶数那么度为1的节点个数等于1,反之则为0。

二叉树的存储结构

二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。

顺序存储

顺序结构存储就是使用数组来存储,一般使用数组只合适表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。
以下是数组结构存储的特点:

leftchild=parent * 2+1;
rightchild=parent*2+2;parent=(child-1)/2;

任意位置通过下标可以找到父亲或者孩子。
总结:满二叉树和完全二叉树适合使用数组储存。

链式存储

二叉树的链式存储结构是指,用链表来表示一颗二叉树,即用链来指示元素的逻辑关系。通常的方法是每个链表中每个节点由三个域组成,数据域和左右指针域,左右指针分别用来表示给出该节点左孩子和右孩子所在的链节点的存储地址。
image.png

结构如下
typedef int BTDataType;
struct BinaryTreeNode
{struct BinaryTreeNode* left;struct BinaryTreeNode*right;BTDataType data;
}

二叉树顺序结构及实现

普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。实现中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。

堆的概念

将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或者小堆根。
堆:非线性结构,完全二叉树
小堆:树中任意一个父亲都<=孩子
大堆:树中任意一个父亲都>=孩子

底层:物理结构,数组
逻辑结构,完全二叉树
小堆,底层数组是否升序呢?不一定。
小堆的根是整棵树的最小值。可以解决的问题:
1、topk问题
2、堆排序

堆的实现

堆的插入

插入数据之后还要保证数据是堆。

堆的定义

底层就是一个顺序表,可以使用数组来存储。

typedef int HPDataType;
typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;

堆的初始化HeapInit

1)断言
2)有两种方式第一种直接置空,第二种开一个空间。

//初始化堆
void HeapInit(HP* php)
{assert(php);php->a = NULL;php->size = php->capacity = 0;
}

打印HeapPrint

1)断言
2)使用循环打印

//打印
void HeapPrint(HP* php)
{assert(php);for (int i = 0; i < php->size; i++){printf("%d ", php->a[i]);}printf("\n");
}

释放空间HeapDestroy

1)断言
2)先释放数组

//释放空间
void HeapDestroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->size = php->capacity = 0;
}

向上调整AdjustUp

1)先算出父节点
2)使用child等于0来结束循环
3)判断孩子节点是否小于父节点,小于的话就交换,同时要修改child和parent的大小
4)反之,则直接退出循环。

void AdjustUp(HPDataType* a, int child)
{//找到父节点int parent = (child - 1) / 2;//当下标小于等于零的时候结束循环while (child>0){if (a[child]<a[parent]){//交换两个数Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{//直接跳出循环break;}}
}

交换函数Swap

需要的参数就是两个指针。
根据传过来的指针,直接交换就好。

void Swap(HPDataType* child, HPDataType* parent)
{int temp = *child;*child = *parent;*parent = temp;
}

插入数据HeapPush

1)断言
2)扩容
3)使用realloc在堆上开辟空间。
4)向上调整,向上调整的时候是需要数组的指针和最后一个数的下标

//插入数据
void HeapPush(HP* php, HPDataType x)
{assert(php);//扩容if (php->size==php->capacity){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* temp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newcapacity);if (temp==NULL){perror("realloc fail");exit(-1);}//把创建的空间分配给aphp->a = temp;//定义容器的大小php->capacity = newcapacity;}php->a[php->size] = x;php->size++;AdjustUp(php->a,php->size-1);
}

向下调整AdjustDown

需要的参数指向数组的指针,元素的个数,跟节点的下标。
1)先找到孩子
使用循环来找孩子,循环的结束条件就是孩子的下标小于元素个数
2)比较两个孩子谁小一点
注意右孩子可能出现越界的情况这需要考虑
3)再比较孩子节点和父节点上的值
如果比父节点上的值小那就交换,再继续向下调整

void AdjustDown(HPDataType* a, int n, int parent)
{int child = parent * 2 + 1;while (child<n){if (child+1<n&&a[child+1]<a[child]){child++;}if (a[child]<a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

删除数据HeapPop

删除根比较有意义。
如果挪动覆盖第一个位置根,关系全乱了。
1)先交换 根和最后一个值交换,再删除。
需要注意的是要控制size的大小因该控制在大于0
交换完之后size需要减1
2)向下调整
传参数的时候要传3个参数,数组,元素个数,根节点。
元素个数用来控制节点的最大下标。

//删除数据
void HeapPop(HP* php)
{//断言assert(php);assert(php->size>0);//交换Swap(&php->a[0], &php->a[php->size - 1]);php->size--;//向下调整AdjustDown(php->a,php->size,0);
}

堆顶的数据HeapTop

只需要堆的指针
1)断言
是否为空指针,是否为空堆
2)返回根

//取堆顶的数据
HPDataType HeapTop(HP* php)
{assert(php);assert(!HeapEmpty(php));return php->a[0];
}

初始化数组HeapInitArray

需要的参数堆的指针,数组指针,开的空间大小
1)断言
判断两个指针是否为空指针。
2)给数组开空间
并判断空间是否开辟完成
3)使用memcpy函数进行复制
4)建堆

//初始化数组
void HeapInitArray(HP* php, int* a, int n)
{assert(php);assert(a);php->a = (HPDataType*)malloc(sizeof(HPDataType)*n);if (php->a==NULL){perror("malloc fail");exit(-1);}php->size = n;php->capacity = n;memcpy(php->a, a, sizeof(HPDataType) * n);for (int i = 0; i < n; i++){AdjustUp(php->a, i);}
}

判空HeapEmpty

只需要堆的指针
1)断言
看指针是否为空
2)返回size是否等于0

//判空
bool HeapEmpty(HP* php)
{assert(php);return php->size == 0;
}

使用堆排序HeapSort

堆排序的特点:就是数组有序
缺点:需要写有一个堆。
向上调整。
排升序,建大堆。
堆顶跟最后一个位置交换,最大的数据就排好了,剩下数据向下调整,选出次大的,代价是logN。合计是:N* logN

//void HeapSort(int* a, int n)
//{
//	HP hp;
//	//初始化
//	HeapInit(&hp);
//	
//	for (int i = 0; i < n; i++)
//	{
//		HeapPush(&hp, a[i]);
//	}
//	
//	int i = 0;
//	while (!HeapEmpty(&hp))
//	{
//		printf("%d ", HeapTop(&hp));
//		a[i++] = HeapTop(&hp);
//		HeapPop(&hp);
//	}
//
//	HeapDestroy(&hp);
//}void HeapSort(int* a, int n)
{// 建堆 (大堆)or  (小堆)for (int i = 1; i < n; i++){AdjustUp(a, i);}int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);--end;}}
void test2()
{int a[] = { 2,3,5,7,4,6,8 };HeapSort(a, sizeof(a) / sizeof(int));
}

向下调整建堆

image.png
image.png
image.png

向上调整

image.png

TopK问题

假设10亿个数据,内存存不下,数据在文件中找出最大的前k个。
1、读取文件的前100个数据,在内存中建立小堆
2、再依次读取剩下数据,跟堆顶数据比较,大于堆顶,就替换他进堆,向下调整
3、所有的数据读完,堆里面数据就是最大的前100个
核心:
建立小堆、时间复杂度:O(N* logK)、空间复杂度:O(K)

void PrintTopK(const char* filename, int k)
{// 1. 建堆--用a中前k个元素建堆FILE* fout = fopen(filename, "r");if (fout==NULL){perror("fopen fail");return;}int* minheap = (int*)malloc(sizeof(int) * k);if (minheap==NULL){perror("malloc fail");return;}for (int i = 0; i < k; i++){fscanf(fout, "%d", &minheap[i]);}//前k个数建小堆for (int i = (k-2)/2; i >=0 ; i--){AdjustDown(minheap, k, i);}// 2. 将剩余n-k个元素依次与堆顶元素交换,不满则则替换int x = 0;while (fscanf(fout,"%d",&x)!=EOF){if (x>minheap[0]){//替换进堆minheap[0] = x;AdjustDown(minheap, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", minheap[i]);}printf("\n");free(minheap);fclose(fout);
}//创建文件
void CreateNData()
{//造数据int n = 1000000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin==NULL){perror("fopen error");return;}for (int i = 0; i < n; i++){int x = (rand() + i) % 1000000;fprintf(fin, "%d\n", x);}fclose(fin);
}int main()
{//CreateNData();PrintTopK("data.txt", 5);return 0;
}

二叉树链式结构及实现

二叉树的遍历(递归遍历)

image.png
普通的链式二叉树没有意义。
1、更复杂二叉树搜索树->AVL 红黑树(以后打基础)
2、很多二叉树的题,是出这一块
image.png
这就是搜索二叉树,左边比根小右边比根大。
搜索二叉树走中序就是排序。

前序遍历PrevOrder

1、先手动构建二叉树

typedef struct BinaryTreeNode
{struct BinaryTreeNode*left;struct BinaryTreeNode*right;int val;
}BTNode;BTNode*BuyNode(int x)
{BTNode*node=(BTNode*)malloc(sizeof(BTNode));if(node==NULL){perror("malloc fail");return;}node->val=x;node->left=NULL;node->right=NUll;return node;
}

2、手动链接

int main()
{BTNode* node1=BuyNode(1);BTNode* node2=BuyNode(2);BTNode* node3=BuyNode(3);BTNode* node4=BuyNode(4);BTNOde* node5=BuyNode(5);BTNode* node6=BuyNode(6);node1->left=node2;node1->right=node4;node2->left=node3;node4->left=node5;node4->right=node6;return 0;
}

3、根 左子树 右子树

void PrevOrder(BTNode*root)
{if(root==NULL){printf("NULL ");return ;}printf("%d ",root->val);PrevOrder(root->left);PrevOrder(root->right);
}

中序遍历InOrder

先左子树 根 右子树

void InOrder(BTNode*root)
{if(root==NULL){printf("NULL ");return ;}InOrder(root->left);printf("%d ",root->val);InOrder(root->right);
}

image.png

后序遍历PostOrder

先左子树 右子树 根

void PostOrder(BTNode*root)
{if(root==NULL){printf("NULL");return ;}PostOrder(root->left);PostOrder(root->right);printf("%d ",root->val);
}

二叉树节点个数TreeSize

方法一:简单的方式就是遍历一遍。
方法二:当前节点的个数等于左子树+右子树+自己
1、当前为空的时候返回0
2、反之就返回左子树+右子树+1

int TreeSize(BTNode* root)
{return root==NULL?0:TreeSize(root->left)+TreeSize(root->right)+1;
}

叶子节点个数TreeLeafSize

1、空->0
2、叶->1
3、左子树+右子树

int TreeLeafSize(BTNode*root)
{if(root==NULL){return 0;}if(root->left==NULL&&root->right==NULL){return 1;}return TreeLeafSize(root->left)+TreeLeafSize(root->right);
}

第k层的节点个数TreeLevel

1、当前树的第k层=左子树的第k-1层+右子树的第k-1层

int TreeLevel(BTNode*root,int k)
{if(root==NULL){return 0;}if(k==1){return 1;}return TreeLevel(root->left,k-1)+TreeLevel(root->right,k-1);
}

二叉树的销毁TreeDestroy

1、子问题
2、返回条件(最小规模的子问题)
3、使用后序遍历的思想进行销毁

void TreeDestroy(BTNode* root)
{if (root==NULL){return;}TreeDestroy(root->left);TreeDestroy(root->right);free(root);
}

二叉树查找值为X的节点TreeFind

BTNode* TreeFind(BTNode* root, int x)
{//如果是空者返回空指针if (root==NULL){return NULL;}//如果找到了就返回当前节点的指针if (root->val==x){return root;}//定义一个指针来接受返回的地址BTNode* ret = NULL;//返回左边ret=TreeFind(root->left, x);//看左边是否为空,不为空就说明找到了,直接返回给上一级地址if (ret){return ret;}ret = TreeFind(root->right, x);//看右边是否为空,不为空就说明找到了,直接返回给上一级地址if (ret){return ret;}//要是走到这个位置也没有返回说明没有找到值return NULL;
}

层序遍历(LevelOrder)

上一层带下一层
先进先出。

void LevelOrder(BTNode* root)
{//首先初始化Que q;QueueInit(&q);if (root){QueuePush(&q, root);}while (!QueueEmpty(&q)){//取头的数据BTNode* front = QueueFront(&q);printf("%d ", front->val);//带入左右子树if (front->left){QueuePush(&q, front->left);}if (front->right){QueuePush(&q, front->right);}QueuePop(&q);}printf("\n");
}

优先遍历

深度优先遍历(DFS)

前序遍历

广度优先遍历(BFS)

层序遍历,配合队列

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/168130.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java读取指定文件夹下的全部文件,并输出文件名,文件大小,文件创建时间

import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.*; import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { try { Path startingDir Paths.get("你的目…

Spring中动态代理设计模式

目录 一、什么是动态代理 二、动态代理开发步骤 2.1 搭建开发环境 2.2 具体过程 三、动态字节码技术 四、动态代理开发简化代理开发 一、什么是动态代理 其实不管是静态代理还是动态代理其本质都是一样的&#xff0c;都是通过代理类为目标类增加额外功能&#xff0c;从而方便目…

自然语言处理---Transformer模型

Transformer概述 相比LSTM和GRU模型&#xff0c;Transformer模型有两个显著的优势&#xff1a; Transformer能够利用分布式GPU进行并行训练&#xff0c;提升模型训练效率。 在分析预测更长的文本时&#xff0c;捕捉间隔较长的语义关联效果更好。 Transformer模型的作用 基于seq…

蓝桥杯每日一题0223.10.23

第几天 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 简单枚举&#xff08;用k来记录经过的天数&#xff09; #include<bits/stdc.h> using namespace std; bool is_ren(int n) {if(n % 400 0 || (n % 4 0 && n % 100 ! 0))return true;return false; } int …

【Android知识笔记】Webview专题

WebView 核心组件 类名作用常用方法WebView创建对象加载URL生命周期管理状态管理loadUrl():加载网页 goBack():后退WebSettings配置&管理 WebView缓存:setCacheMode() 与JS交互:setJavaScriptEnabled()WebViewClient处理各种通知&请求事件should

为什么红黑树比AVL树效率高?

文章目录 前言红黑树的提出都知道的几个定义理解红黑树的高效总结 前言 红黑树为什么这么火呢&#xff1f;大家应该都很清楚&#xff0c;面试的时候不管三七二十一&#xff0c;就问你&#xff1a;什么是红黑树&#xff0c;为什么要用红黑树&#xff1f;就好像他很懂&#xff0…

CUDA学习笔记5——CUDA程序错误检测

CUDA程序错误检测 所有CUDA的API函数都有一个类型为cudaError_t的返回值&#xff0c;代表了一种错误信息&#xff1b;只有返回cudaSuccess时&#xff0c;才是成功调用。 cudaGetLastError()用来检测核函数的执行是否出错cudaGetErrorString()输出错误信息 #include <stdi…

项目快讯|深汕特别合作区气膜羽毛球馆正式开工

“永不坍塌”的气膜运动馆 “安全”是每个行业可持续发展的核心原则、是每个企业长久生存的重要底线、是每个人追求幸福生活的基本保障。 任何新行业、新技术、新材料、新工艺的发展都需要逐步规范化的企业标准、行业标准、国家标准。 气承膜技术发展的初期&#xff0c;面临行业…

springboot+vue基于Spark的共享单车数据存储系统的设计与实现【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

BadNets: Identifying Vulnerabilities in the Machine Learning Model Supply Chain

BadNets: Identifying Vulnerabilities in the Machine Learning Model Supply Chain----《BadNets:识别机器学习模型供应链中的漏洞》 背景&#xff1a; 许多用户将训练过程外包给云计算&#xff0c;或者依赖于经过训练的模型&#xff0c;然后根据特定的任务对模型进行微调。这…

【python】机器学习-K-近邻(KNN)算法

目录 一 . K-近邻算法&#xff08;KNN&#xff09;概述 二、KNN算法实现 三、 MATLAB实现 四、 实战 一 . K-近邻算法&#xff08;KNN&#xff09;概述 K-近邻算法&#xff08;KNN&#xff09;是一种基本的分类算法&#xff0c;它通过计算数据点之间的距离来进行分类。在…

TCP--拥塞控制

大家好&#xff0c;我叫徐锦桐&#xff0c;个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识&#xff0c;还有日常折腾的经验&#xff0c;欢迎大家来访。 TCP中另一个重要的点就是拥塞控制&#xff0c;TCP是无私的当它感受到网络拥堵了&#xff0c;就…

transformer理解

李宏毅老师讲解的Transformer&#xff0c;非常简单易懂&#xff1a;https://www.youtube.com/watch? RNN存在的问题是&#xff0c;只有得到t(i)时刻的向量信息才能够计算t(i1)时刻的向量信息&#xff0c;无法实现并行化。无法实现长序列的特征信息提取&#xff0c;超过一篇文章…

【C++】哈希应用——海量数据面试题

哈希应用——海量数据面试题 一、位图应用1、给定100亿个整数&#xff0c;设计算法找到只出现一次的整数&#xff1f;2、给两个文件&#xff0c;分别有100亿个整数&#xff0c;我们只有1G内存&#xff0c;如何找到两个文件交集&#xff1f;&#xff08;1&#xff09;用一个位图…

Node.js与npm版本比对

Node.js与npm版本比对 Node.js与npm版本比对版本对比表Node版本对比 Node.js与npm版本比对 我们在项目开发过程中&#xff0c;经常会遇到公司一些老的前端工程项目&#xff0c;而我们当前的node及npm版本都是相对比较新的了。 在运行以前工程时&#xff0c;会遇到相关环境不匹…

浅谈uniapp中开发安卓原生插件

其实官方文档介绍的比较清楚而且详细,但是有时候他太墨迹,你一下子找不到自己想要的,所以我总结了一下开发的提纲,也是为了自己方便下次使用。 1.第一步,下载官方提供的Android的示例工程,然后倒入UniPlugin-Hello-AS工程请在App离线SDK中查找,之后Android studio,编译运行项目…

不会用PS抠图?教你懒人抠图法,必须学会!

相信很多小伙伴都有遇到这样的窘境——好不容易找到得素材图片&#xff0c;中间的图案很好看&#xff0c;可是特别想去掉后面的背景&#xff0c;应该如何抠图呢&#xff1f; 能够将图片中的物品或人物抠出来是一种很有用的技巧&#xff0c;可以在很多场景下应用&#xff0c;比…

MySQL -- 环境安装(CentOS7)

MySQL – 环境安装&#xff08;CentOS7&#xff09; 文章目录 MySQL -- 环境安装&#xff08;CentOS7&#xff09;一、环境安装1.卸载不必要的环境2.检查系统安装包3.卸载默认安装包4.获取MySQL官方yum源6.看看yum源能不能正常工作7.安装mysql服务 二、MySQL登录与配置1.启动My…

论文阅读 - Coordinated Behavior on Social Media in 2019 UK General Election

论文链接&#xff1a; https://arxiv.org/abs/2008.08370 目录 摘要&#xff1a; Introduction Contributions Related Work Dataset Method Overview Surfacing Coordination in 2019 UK GE Analysis of Coordinated Behaviors 摘要&#xff1a; 协调的在线行为是信息…

造车先做三蹦子220101--机器学习字符(字母、和数字识别)的“小白鼠”与“果蝇”

“0”数字字符零 的图片(16*16点阵)&#xff1a; #Letter23Digital23R231006d.pyimport torch import torch.nn as nn import torch.optim as optim #optimizer optim.SGD(model.parameters(), lr0.01) from PIL import Image from PIL import ImageDraw from PIL import Im…