数据结构——图

news2024/11/17 8:30:08

文章目录

    • **一 图的基本概念**
      • **1 定义**
    • **二 图的存储及基本操作**
      • **1 邻接矩阵法**
      • **2 邻接表法**
      • **3 十字链表**
      • **4 邻接多重表**
      • **5 图的基本操作**
    • **三 图的遍历**
      • **1 广度优先搜索BFS**
      • **2 深度优先搜索DFS**
      • **3 图的遍历与连通性**
    • **四 图的应用**
      • **1 最小生成树**
        • **==1.1 Prim(普里姆)算法==**
        • **==1.2 Kruskal(克鲁斯卡尔)算法==**
      • **2 最短路径**
        • **==2.1 Dijkstra算法求单源最短路径问题==**
        • **==2.2 Floyd算法求各顶点直接最短路径问题==**
        • **2.3 有向无环图描述表达式**
        • **==2.4 拓扑排序==**
        • **==2.5 关键路径==**

一 图的基本概念

1 定义

图G由顶点集V和边集E组成,记为G=(V,E);|V|表示顶点个数,|E|表示边的条数

线性表可以是空表,树可以是空树,但是图不能是空图

(1)有向图

在这里插入图片描述

从顶点1到顶点2,1称为弧尾,2称为弧头

(2)无向图

没有方向的边

在这里插入图片描述

(3)简单图,多重图

简单图:不存在重复的边,不存在顶点到自身的边,如上面两图

多重图:某两个顶点直接的边数大于1条,又允许顶点通过一条边和自身相连

(4)完全图(简单完全图)

对于无向图,有n*(n-1)/2条边的无向图称为完全图,其任意两个顶点之间都存在边

对于有向图,有==n(n-1)==条弧的有向图称为有向完全图,其任意两个顶点之间都存在方向相反的两条弧

在这里插入图片描述

(5)子图

如有两个图G,G`,V’是V的子集,E‘是E的子集,则G’是G的子图

若V(G’)=V(G)的子图G’,则称其为G的生成子图

但不是任意子集都能构成子图,有些可能甚至不是图

(6)连通,连通图和连通分量

连通:无向图中,顶点v到顶点w有路径存在,则v和w连通的

连通图:图G中任意两个顶点都是连通的,否则称为非连通图

无向图中的极大连通子图称为连通分量

如果一个图有n个顶点,边数小于n-1,则必是非连通图;同理,如果图是非联通图,那么最多有n-2条边

在这里插入图片描述

(7)强连通图,强连通分量

强连通:有向图中,一对顶点v和w,从v到w和从w到v都有路径,称他们为强连通

强连通图:图中任何一对顶点都是强连通的

有向图中的极大强连通子图称为有向图的强连通分量

一个n个顶点的强连通图最少有n+1条边

在这里插入图片描述

(8)生成树,生成森林

连通图的生成树是包含图中全部顶点的一个极小连通子图,若有n个顶点,则含有n-1条边

去掉一个边就是非连通图,加一个边就形成回路

非连通图中,连通分量的生成树构成了非连通图的生成森林

在这里插入图片描述

极大连通子图:无向图的连通分量,要求该连通子图包含所有的边

极小连通子图:既要保持图连通,又要使得边数最少的子图

(9)顶点的度,入度和出度

无向图中,顶点v的度是指依附于v的边的条数,记为TD(v),每个顶点都要算一次,n条边就2n的度

有向图中,入度是以顶点v为终点的有向边的数目,记为ID(v),出度是以顶点v为起点的有向边的树,记为OD(v),度就是两者之和,且整个图的ID=OD=n(图的边数)

(10)边的权和网

每条边标上具有某种含义的数值称为该边的权值,这种带有权值的图称为带权图也称网

(11)稠密图,稀疏图

边数多就是稠密,少就是稀疏,是相对概念

(12)路径,路径长度和回路

顶点v到w经过的顶点序列就是路径,路径上的边就是路径长度,第一个顶点和最后一个顶点相同的路径成为回路或环

n个顶点,大于n-1条边的图一定有环

(13)简单路径,简单回路

简单路径:路径序列中顶点不重复出现

简单回路:除第一个顶点和最后一个顶点外,其余顶点不重复出现的回路

(14)距离

距离:顶点v到w的最短路径长度,不存在就标记为无穷

(15)有向树

一个顶点的入度为0,其余顶点的入度均为1的有向图

二 图的存储及基本操作

1 邻接矩阵法

指用一个一维数组存储图顶点信息,用一个二维数组存储图中边的信息

邻接矩阵:存储顶点直接邻接关系的二维数组

#define maxvertexnum 100         \\顶点数目
typedef char vertextype;         \\顶点的数据类型
typedef int edgetype;            \\带权图中边上权值的数据类型
typedef struct
{
    vertextype Vex[maxvertexnum];               \\顶点表
    edgetype Edge[maxvertexnum][maxvertexnum];  \\邻接矩阵,边表
    int vexunm,arcnum;                          \\当前顶点数和弧数
}

A[i][j]=10  表示从顶点i到j存在边就是1,否则是0
对带权图,A[i][j]=w 表示从i到j的权值是w,如不存在边就是0或者无穷

在这里插入图片描述

无向图的邻接矩阵是对称矩阵,并且唯一,可采用压缩存储;第i行非零元素的个数正好是顶点i的度

对有向图的第i行非零是i的出度,第i列非零是入度

邻接矩阵表示法的空间复杂度为O(n2),n是顶点数

要确定边数需要按行和列进行检测,时间慢,适合稠密图

邻接矩阵A,An的元素An[i][j]等于从i到j的长度为n的路径数目

2 邻接表法

对图的每个顶点vi建立一个单链表,第i个单链表中的结点表示依附于vi的边(对于有向图就是以vI为尾的弧),称为边表(对有向图就是出边表)

边表的头指针和顶点的数据信息采用顺序存储(顶点表),所以有顶点表结点和边表结点

在这里插入图片描述

#define maxvertexnum 100        \\顶点数目

typedef struct Arcnode          \\边表结点
{
    int adjvex;                 \\该弧指向顶点的位置
    struct Arcnode *next;       \\指向下一条弧的位置
    \\Infotype info;            \\边权值
}Arcnode;

typedef struct Vnode             \\顶点表结点
{
    Vertextype data;             \\顶点信息
    Arcnode *first;              \\指向第一条依附该顶点的弧的指针
}Vnode,Adjlist[maxvertexnum];

typedef struct
{
    Adjlist vertices;            \\邻接表
    int vexnunm,arcnum;          \\图的顶点数和弧数
}Algraph;

在这里插入图片描述

(1)无向图的存储空间为O(|v|+|2e|),有向图存储空间为O(|V|+|E|)

(2)适合稀疏图,极大的节省空间

(3)若要确定两个顶点间是否存在边,邻接矩阵可以直接查到,邻接表需要在相应的结点对应的边表中查找另一结点,效率较低

(4)有向图邻接表,顶点的出度只需看邻接表的结点个数,但是入度要查整个表

(5)链表次序不唯一

3 十字链表

十字链表中,对应有向图中的每条弧有一个结点,对应每个顶点也有一个结点

在这里插入图片描述

tailvex:指示弧尾顶点的编号

headvex:指示弧头顶点的编号

hlink:指向弧头相同的下一个弧结点

tlink:指向弧尾相同的下一个弧结点

info:存放弧的相关信息

弧头相同的就在同一个链表,弧尾相同的在同一个链表

data:顶点的数据信息

firstin:指向以该顶点为弧头的第一个弧结点

firstout:指向以该结点为弧尾的第一个弧结点

顶点结点之间顺序存储,很容易找到头和尾,即出入度

在这里插入图片描述

4 邻接多重表

无向图的另一种链式存储,每条边都用一个结点表示

在这里插入图片描述

ivex和jvex指示该边依附的两个顶点的编号;ilink指向下一条依附于顶点ivex的边,jlink指向下一条依附于顶点jvex的边;info存放边的相关信息

在这里插入图片描述

data:顶点信息

firstedge:指向第一条依附于该顶点的边

所有依附于同一顶点的边串联在同一链表中,每个边结点同时链接在两个链表中

在这里插入图片描述

5 图的基本操作

仅抽象考虑

Adjacent(G,x,y); \\判断G是否存在边<x,y>
Neighbors(G,x);  \\列出图G中与结点x邻接的边
Insertvertex(G,x);\\插入顶点x
Deletevertex(G,x);\\删除x
Addedge(G,x,y);   \\若边<x,y>不存在,则添加
Removeedge(G,x,y);\\若边<x,y>存在,则删除
Firstneighbor(G,x);\\求顶点x的第一个邻接点,有返回顶点号,没有或不存在x返回-1
Nextneighbor(G,x,y);\\y是x的一个邻接点,返回除y的下一个邻接点,没有返回-1
Get_edge_value(G,x,y);\\获取权值
Set_dege_value(G,x,y,v);\\设置边的权值为v                

三 图的遍历

1 广度优先搜索BFS

基本思想:访问起始结点v,从v出发,依次访问v的各个未访问过的邻接结点w1….wn,然后再依次访问w1….wn的所有未被访问过的邻接结点,然后再循环从结点出发,访问未被访问过的邻接结点,直到全部访问完毕

若还有没被访问的,重新选一个起始结点重复上述过程,直到全部访问完毕

dijkstra算法和prim最小生成树算法应用了这种思想

是一种分层的查找过程,类似树的层序遍历,需要借助队列,伪代码如下:

bool visited[maxvertexnum];              \\标记数组
void BFStraverse(Graph G)
{
    for(int i =0;i<G.vexnum;i++)         \\初始化标记数组
    {
        visited[i]=false;
    }
    Initqueue(Q);
    for(int i =0;i<G.vexnum;i++)        \\从0号顶点开始遍历
    {
        if(!visited[i])
        {
           BFS(G,i);                    \\每个连通分量一次BFS,没被访问过就BFS
        }
    }
}

void BFS(Graph G,int v)                   \\从v出发,遍历G
{ 
    visit(v);                             \\访问v
    visited[v]=true;                      \\置为true防止多次访问
    Enqueue(Q,v);                          \\v入队列
    while(!isempty(Q))                   
    {
        Dequeue(Q,v);                     \\v出队列
        for(w=Firstneighbor(G,v);w>=0; w=Nextneighbor(G,v,w))   \\检测v的所有邻接接点
        {
            if(!vitited[w])                   \\w为v未访问过的邻接接点
            {
                visit(w);       
                visited[w]=true;
                Enqueue(Q,w);                \\访问w后,w再入队列
            }
        }
    }
}

图的广度优先搜索和二叉树的层序遍历基本一致

BFS的算法性能分析

空间复杂度为O(|V|)

时间复杂度:(1)邻接表:O(|V|+|E|)

(2)邻接矩阵:O(|V|2)

BFS算法求解单源最短路径的问题

非带权图的最短路径d(u,v):从u到v的任何路径中最少的边数,没有则置为无穷

void BFSmindistance(Graph G,int u)
{
    \\d[i]表示u到i的最短路径
        for(int i =0;i<G.vextun;i++)
        {
            d[i]=;
        }
    visited[u]=true;d[u]=0;
    Enqueue(Q,u);
    while(!isempty(Q))
    {
        Dequeue(Q,u);                        \\队头元素u出队
        for(w =Firstneighbor(G,u); w>=0; w=Nextnrighbor(G,u,w))
        {
            if(!visited[w])                    \\w为u未访问的邻接结点
            {
                visited[w]=true;
                d[w]=d[u]+1;                  \\路径长度加1
                Enqueue(Q,w);
            }
        }
    }
}

广度优先生成树

遍历过程中可以得到一颗遍历树

邻接矩阵的树唯一,但是邻接表的不唯一

在这里插入图片描述

2 深度优先搜索DFS

类似树的先序遍历,尽可能“深”的搜索一个树

基本思想:访问起始顶点v,从v出发,访问与c邻接且未被访问的任意一个顶点w1,再访问与w1邻接且未被访问的任意一个顶点w2,重复这个过程,不能向下访问的时候,依次退回最近被访问的顶点, 若它还有未被访问的邻接顶点,则再从这个顶点开始搜索,直到图访问完毕

递归算法:

bool visited[maxvertexnum];
void DFStraverse(Graph G)
{
    for(int v=0 ;v<G.vextum;v++)
    {
        visited[v]=false;
    }
    for(int v = 0;v<G.vextum;v++)
    {
        if(!visited[v])
        {
            DFS(G,v);
        }
    }
}

void DFS(Graph G,int v)
{
    visit(v);
    visited[v]=true;
    for(w=Firstneighbor(G,v); w>=0; w=Nextneighbor(G,v,w))
    {
        if(!visited[w])
        {
            DFS(G,w);
        }
    }
}

DFS遍历的序列,邻接矩阵唯一,邻接表不唯一

DFS算法的性能分析

需要一个递归工作栈,空间复杂度为O(|V|)

时间复杂度:(1)邻接矩阵:O(|v|2)

(2)邻接表:O(|V|+|E|)

深度优先的生成树和生成森林

连通图调用DFS才能产生深度优先生成树,否则产生的是深度优先生成森林

3 图的遍历与连通性

无向图调用DFS,BFS的次数等于图的连通分量数

连通有向图分为强连通个非强连通,连通子图也分为强连通分量和非强连通分量

非强联分量一次调用BFS(G,i)或DFS无法访问到该连通分量的所有顶点

四 图的应用

1 最小生成树

一个带权连通无向图G,生成树不同,每棵树的权也可能不同,若T为权值之和最小的那颗生成树,则T为G的最小生成树MST

性质:

(1)最小生成树不唯一

(2)最小生成树的边的权值之和唯一

(3)最小生成树的边数为顶点数减1

根据性质从最小权值的边开始,基于贪心算法的有Prim和Kruskal算法

1.1 Prim(普里姆)算法

基本思想:任取一个顶点,找权值最小边并且不是重复顶点的边加入,直到所有顶点加入

n个顶点,T必有n-1条边

在这里插入图片描述

void Prim(G,T)
{
    T=;                           \\初始化空树
    U={w};                          \\添加任意一个顶点w
    while((V-U)!=)
    {(u,v)是使得u属于U与v属于(V-U),且权值最小的边;
        T=T∪{(u,v)};                \\边归入树
        U=U∪{v};                    \\顶点归入树
    }
}

时间复杂度:O(|V|2)

1.2 Kruskal(克鲁斯卡尔)算法

是一种按权值的递增次序选择合适的边来构造最小生成树的方法

在这里插入图片描述

void Kruskal(G,T)
{
    T=V;                           \\初始化T,仅含顶点
    numS=n;                        \\连通分量数,初始就是顶点总数
    while(numS>1)
    {
        从E中取权值最小的边(v,u)
        if((v,u)属于不同连通分量)
        {
             T=T∪{(u,v)};                \\边归入树
             numS--; 
        }
    }
}

时间复杂度:O(log2|E|)

2 最短路径

一个顶点到另一个顶点的路径的权值之和最短称为最短路径;两点直接的最短路径也包含了路径上其他顶点间的最短路径

单源最短路径:求图中某一顶点到其他各顶点的最短路径,可通过Dijkstra算法

每对顶点间的最短路径:Floyd算法求解

2.1 Dijkstra算法求单源最短路径问题

设置一个集合S记录已求得的最短路径的顶点,初始时把源点v0放入S,集合S每并入一个新顶点vi,都要修改源点v0到集合V-S中顶点当前的最短路径长度值。

设置两个辅助数组:

dist[]:记录源点v0到其他各顶点当前的最短路径长度,初态为:若从v0到vi有弧,则dist[i]为弧上的权值,否则置为无穷

path[]:path[i]表示从源点到顶点i之间的最短路径的前驱结点

初始S只包含顶点0;邻接矩阵arcs表示带权有向图,arcs[i] [j]表示边<i,j>的权值,不存在就置为无穷

算法步骤:

(1)初始化:S初始为{0},dist[i]=arcs[0] [i],i=1,2,3,……n-1

(2)从顶点集合V-S中选出vj,满足dist[j]=Min{dist[i]|vi ∈ \in V-S},vj就是当前求得的一条从v0出发的最短路径的终点,S=S ⋃ \bigcup {j}

(3) 修改从v0出发到集合V-S上任意一个顶点Vk可达的最短路径长度,若dist[j]+arcs[j] [k]<dist[k],则更新dist[k]=dist[j]+arcs[j] [k]

(4)重复2-3的操作n-1次,直到所有顶点都包含在S中,基于贪心策略

举例:

在这里插入图片描述

(1)初始化S,v1可达v2和v5,不可达v3和v4;故dist[2]=0,dist[3]=∞,dist[4]=∞;dist[5]=5

(2)选出最小值dist[5],将顶点v5并入集合S,此时找到1-5的最短路径;5加入后,1到集合V-S中可达顶点的最短路径长度可能会产生变化,更新dist[]数组,5可达2,1-5-2的距离8比dist[2]=10小,更新dist[2]=8;5可达3,1-5-3的距离14,更新dist[3]=14;5可达4,1-5-4的距离是7,更新dist[4]=7

(3)再选出最小值,dist[4],顶点4并入S,再更新dist[]数组;4不可达2,不变;4可达3,1-5-4-3距离是13比dist[3]小,更新dist[3]=13

(4)再选出最小的dist[2],顶点2并入S;更新dist[];2可达3,1-5-2-3的距离是9,比dist[3]小,更新dist[3]=9

(5)选出唯一的最小值dist[3],并入S,此时全部顶点并入完毕

无论是邻接矩阵还是邻接表的时间复杂度都是O(|V|2)

但是当边有负权值时,Dijkstra算法失效

在这里插入图片描述

例如图a,0到1和2的距离分别是7和5,那么就会首先并入顶点2,距离为5,再并入顶点1,但是并入顶点1时,从0到2的距离最小实际是2,不是5,但由于已经并入了2,无法更新

2.2 Floyd算法求各顶点直接最短路径问题

求出任意两个顶点i和j之间的最短路径和最短路径长度

基本思想:递推产生一个n阶方阵序列A(-1),A(0),A(1)……A(n-1),其中A(k)[i][j]表示从顶点i到顶点j的路径长度,k表示绕行第k个顶点的运算步骤。

初始时,任意两个顶点i和j直接存在边,则在边上的权值作为它们之间的最短路径长度;不存在有向边就用∞作为长度。

然后逐步尝试在原路径中加入顶点k作为中间顶点,若增加中间顶点后,得到的路径比原来的路径长度减少了,新路径就代替原路径

算法描述:

定义一个n阶方阵序列A(-1),A(0),A(1)……A(n-1),其中A(k)[i][j]=arcs[i] [j]

A(k)[i][j]=Min{A(k-1)[i][j],A(k-1)[i][k]+A(k-1)[k][j]},k=0,1……n-1

A(0)[i][j]是从顶点i到j,中间顶点是0的最短路径的长度;A(k)[i][j]是从顶点i到j,中间顶点的序号不大于k的最短路径的长度

这是一个迭代的过程,每迭代一次多考虑一个顶点;A(n-1)[i][j]就保存了任意一对顶点之间的最短路径长度

举例:

在这里插入图片描述

在这里插入图片描述

(1)初始化:方阵A(-1)[i][j]=arcs[i] [j]

(2)把0作为中间顶点,对所有顶点有A(-1)[i][j]>A(-1)[i][0]+A(-1)[0][j],把A(-1)[i][j]更新为A(-1)[i][0]+A(-1)[0][j];更新后方阵记为A0

(3)把1作为中间顶点,继续检测所有顶点,例如有A(0)[0][2]>A(0)[0][1]+A(0)[1][2]=10,更新,新方阵记为A1

(4)把2作为中间顶点,继续,更新方阵为A2,A2就是保存的任意顶点对的最短路径长度

时间复杂度:O(|V|3),但代码紧凑,对中等规模的输入来说仍然有效

允许图中有带负权值的边,但不允许与包含带负权值的边组成的回路;也适用于带权无向图

也可以用单源最短路径算法解决每对顶点之间的最短路径问题,轮流将每个顶点作为源点,在所有边权值均非负时,运行一次Dijkstra算法,时间复杂度为O(|V|3)

2.3 有向无环图描述表达式

若一个有向图不存在环,就成为有向无环图,简称为DAG图

例如((a+b)*(b*(c+d)+(c+d)*e))*((c+d)*e)

在这里插入图片描述

2.4 拓扑排序

AOV网:若用DAG图表示一个工程,其顶点表示工地,边表示活动i必须先于活动j进行的一种关系,则将这种有向图称为顶点表示活动的网络,边没有权值

拓扑排序:在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足以下条件时称为一个图的拓扑排序:

(1)每个顶点只出现一次

(2)若顶点A在序列中排在顶点B的前面,则在图中不存在从B到A的路径

拓扑排序是对有向无环图的的顶点的一种排序,使得若存在一条从顶点A到顶点B的路径,则在排序中顶点B出现在顶点A的后面,每个AOV网都有一个或多个拓扑排序序列

常见算法步骤:

(1)从AOV网中厕一个没有前驱的顶点输出

(2)删除该顶点和它为起点的有向边

(3)重复1,2直到没有顶点为止

在这里插入图片描述

bool Topologicalsort{Graph G}
{
    Initstack(S);
    int i ;
    for(i=0;i<G.vextum;i++)
    {
        if(indegree[i]==0)        \\所有入度为0的顶点入栈
        {
            Push(S,i);
        }
    }
    int count =0;                 \\记录当前输出的顶点数
    while(!isempty(S))
    {
        Pop(S,i);
        print[count++]=i;              \\输出顶点i
        for(p=G.vertices[i].firstarc; p ; p=p->nextarc) \\所有i执行的顶点的入度减1,并把入度为0的入栈
        {
            v=p->adjvex;
            if(!(--indegree[v]))
            {
                Push(S,v);             
            }
        }
    }
    if(count<G.vexnum)
        return false;                 \\有环路 失败
    else
        return true;
}

邻接表:O(|V|+|E|)

邻接矩阵:O(|V|2)

逆拓扑排序:

(1)选一个出度为0 的顶点输出

(2)删除顶点和它以它为终点的有向边

(3)重复1,2直到AOV网空

2.5 关键路径

AOE网:顶点表示事件,有向边表示活动,边的权值表示完成活动的开销,是有向无环图

性质:(1)只有某顶点的事件发生后,从该顶点出发的各有向边所代表的活动才能开始

(2)进入某顶点的各有向边的活动都结束时,该顶点代表的事件才发生

(3)仅有一个入度为0的顶点,称为开始顶点(源点);仅有一个出度为0的顶点,称为结束顶点(汇点)

(4)有些活动可以并行进行

(3)源点到汇点的所有路径中,具有最大路径长度的路径称为关键路径,关键路径的长度就是完成工程的最短时间

寻找关键活动的参量:

(1)事件vk的最早发生时间ve(k)

(2)事件vk的最迟发生时间vl(k)

(3)活动ai的最早开始时间e(i)

(4)活动ai的最迟开始时间l(i)

(5)一个活动ai的最迟开始时间l(i)和最早开始时间e(i)的差额d(i)=l(i)-e(i)

l(i)-e(i)=0,即活动aI是关键活动

算法步骤:

(1)从源点出发,ve(源点)=0,按拓扑有序求其余顶点的最早发生时间ve()

(2)从汇点出发,令vl(汇点)=ve(汇点),按逆拓扑有序求其余顶点的最迟发生时间vl()

(3)根据各顶点的ve()值求所有弧的最早开始时间e()

(4)根据各顶点的vl()值求所有弧的最迟开始时间l()

(5)求AOE网中的所有活动的差额d,找出所有d=0的活动构成关键路径

怎么求ve,ve就是从源点到这个点的耗时最长的数值

怎么求vl,从汇点倒着来,用汇点的值减去汇点到这个点的最小的值(尽量小的到达这个),所以vl ⩾ \geqslant ve

e就是弧起点的顶点的ve

l(i)等于该弧的终点的顶点的vl()减去弧的持续时间

在这里插入图片描述

关键路径上的所有活动都是关键活动

网中的关键路径并不唯一,只有加快所有关键路径上的关键活动才能缩短工期

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

源码编译安装LAMP

文章目录 一.Apache1.什么是apache2.apache的主要特点3.apache的软件版本4.编译安装优点 二.LAMP简介与概述1.LAMP平台概述2.构建LAMP平台顺序3.各组件的主要作用 三.LAMPDISCUZ论坛搭建1.部署Apache1.1 下载apache相关安装包放入服务器中1.2 解压apache的安装进行安装1.3 编译…

SF授权系统源码 V3.7全开源无加密版本

&#x1f389; 有需要的朋友记得关赞评&#xff0c;文章底部来交流&#xff01;&#xff01;&#xff01; &#x1f389; ✨ 源码介绍 2023全新SF授权系统源码 V3.7全开源无加密版本。网站搭建很简单&#xff0c;大致看来一下应该域名解析后上传源码解压&#xff0c;访问域名/i…

如何构建LAMP平台:Apache,MySQL,PHP

如何构建LAMP平台&#xff1a;Apache&#xff0c;MySQL&#xff0c;PHP 一、Apache网站服务&#xff1a;1. Apache的起源&#xff08;多系统兼容&#xff09;&#xff1a;2.重要特点&#xff1a;3.软件版本&#xff1a;4.编译安装呢http服务器&#xff1a; 二、LAMP简介与概述&…

家中群晖NAS遇到断电如何自动关机

群晖NAS遇到断电时如何自动关机 前置条件实现功能的想法具体实施的步骤开启群晖Linux的SSH登陆安装Putty或是Xshell远程登陆上群晖创建计划任务 前置条件 需要一台UPS&#xff08;品牌功能不限&#xff0c;只需续航5分钟以上就可以&#xff09; 实现功能的想法 通过监控网卡…

【备战秋招】每日一题:4月8日美团春招第二题:题面+题目思路 + C++/python/js/Go/java带注释

为了更好的阅读体检&#xff0c;为了更好的阅读体检&#xff0c;&#xff0c;可以查看我的算法学习博客第二题-必经之路 在线评测链接:P1167 题目内容 塔子哥的班主任最近组织了一次户外拓展活动&#xff0c;让班里的同学们一起去爬山。在路上&#xff0c;塔子哥看到了一棵漂…

Windows7 环境下的 Python 版本如何选取?

背景 我需要在不连接互联网的 Windows7 办公电脑上为网页版的办公系统开发一个自动化工具&#xff0c;可以将日常琐碎的操作替代掉。 基本确定了通过 PythonSelenium 的方式来实现网页自动化功能。 首先我需要配置开发环境&#xff0c;安装 Python、VS Code、导入Selenium库、…

提高 React 性能的技巧

1.解决重复渲染问题 我们大多数人都知道虚拟 DOM 是如何工作的&#xff0c;但最重要的是检测何时触发树比较。当我们可以跟踪它时&#xff0c;我们可以控制组件的重新渲染&#xff0c;并最终防止意外的性能流。令人惊讶的是&#xff0c;它并不难捕捉。首先&#xff0c;将 Reac…

uniapp APP端在线升级功能实现讲解——强制或可选升级,下载进度显示

文章目录 概要 需求分析 技术实现梳理 1.是否更新判断&#xff1a; 2.升级弹窗的展示 3.根据升级类型限制操作 4.下载APP监听下载进度 5.下载完自动安装 核心API讲解 1.plus.downloader.createDownload(url,options,completedCallback)&#xff08;下载&#xff09; 2.plus.r…

使用SOCKET搭建linux和window实现实时摄像头传输(linux传输win端使用C++mfc显示)--Win端开发

1.使用MFC搭建框架 配置: Window10VS2013opencv249 如果VS和opencv配置不一样&#xff0c;让版本对应 Opencv与VS版本 1.1 MFC项目搭建 通过这些步骤就创建了一个MFC基础项目。 1.2项目属性配置 本项目因为要使用opencv,所以就要配置以下opencv的环境 首先在opencv官网下载…

手机连接adb 相关问题汇总

目录 关于端口占用问题1 关于修改adb 端口配置问题2 方法3 方法4 关于端口占用问题1 转载链接&#xff1a;https://www.jianshu.com/p/902a89b06271 报错信息&#xff1a; error: no device/emulators found error: device still connecting 解决方案&#xff1a; 重启…

Day_50小结

目录 一. 比较和分析各种查找算法 二. 描述各种排序算法的特点和基本思想&#xff06;比较分析各种排序算法 1. 插入排序 2. 交换排序 3. 选择排序 4. 外部排序 三. 设计一个自己的 Hash 函数和一个冲突解决机制 1. 对于哈希函数的构造&#xff1a; 2. 处理冲突的办法&#…

Mybatis持久层框架 | Lombok搭建

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Lombok Lombok项目是一个java库&#xff0c;它可以自动插入到编辑器和构建工具中&#xff0c;增强java的性能。不需要再写getter、setter或equals方法&#xff0c;只要…

易语言使用node编译的js文件

环境配置 npm install -g cnpm babel-preset-env babel-cli babel-polyfill browserifynpm install -g crypto-js nodejs转js 例如加密模块 browserify -r babel-polyfill -r crypto-js -o es6.txt browserify file.js -o es6.txt易语言 使用v8 推荐 直接生成导入js即…

LMV331TP-TR 滞后比较器实现精确电压比较与判决

文章目录 LMV331TP-TR1. 滞后比较器的基本概念和作用2. LMV331TP-TR 的特性和规格2.1 工作电压范围2.2 输入电压偏置2.3 响应时间 3. LMV331TP-TR 的工作原理3.1 内部结构3.2 滞后器功能的实现原理 4. 实现准确比较和判决的案例 LMV331TP-TR LMV331TP-TR 是一款优秀的滞后比较…

机器学习之逻辑回归模型

1 逻辑回归模型介绍 逻辑回归(Logistic Regression, LR)又称为逻辑回归分析&#xff0c;是一种机器学习算法&#xff0c;属于分类和预测算法中的一种&#xff0c;主要用于解决二分类问题。逻辑回归通过历史数据的表现对未来结果发生的概率进行预测。例如&#xff0c;我们可以将…

web存储(Storage)

目录 1、基本概念 2、功能监测 2.1 测试可用性 2、W3C标准 3、基本方法或属性 4、 Local Storage 4.1 描述 4.2 示例 5、sessionStorage 5.1 描述 5.2 示例 6、StorageEvent&#xff08;存储事件&#xff09; 6.1 构造函数 6.2 实例属性 6.3 实例方法 6.4 响应…

chatgpt赋能python:Python自动缩进详解

Python 自动缩进详解 作为一门面向对象的高级编程语言&#xff0c;Python 其中一个非常重要的特性便是自动缩进。Python 中的代码块是通过缩进来表示的&#xff0c;而不是通过括号或其他方式。这对于刚开始学习 Python 的初学者来说可能是很困难的&#xff0c;但一旦掌握了这一…

开好会议的方法 会议达成共识 明确目标,促成共识 单向会议 互动会议 会议讨论,文档先行 会前文档 会中 3D法则讨论 同步会议,跟进代办 举个栗子 企业管理

目录 开好会的方法 明确目标&#xff0c;促成共识 单向会议 互动会议 会议讨论&#xff0c;文档先行 会前文档 会中 3D法则讨论 同步会议&#xff0c;跟进代办 举个栗子 开好会的方法 会议有时候时间很长&#xff0c;很多无意义内容&#xff0c;如何开出有意义有价值…

Linux学习之权限表现

groupadd grouptest1添加一个叫grouptest1的用户组。 useradd gooduser -g grouptest1添加一个叫gooduser 的用户&#xff0c;并把它添加到grouptest1用户组里边&#xff0c;id gooduser看一下用户的信息。 接下来进行测试用户和用户组权限。 普通文件 在root账户下&#xf…

AI Chat 设计模式:2. 工厂设计模式

本文是该系列的第二篇&#xff0c;采用问答式的方式展开&#xff0c;问题由我提出&#xff0c;答案由 Chat AI 作出&#xff0c;灰色背景的文字则主要是我的旁白。 问题列表 Q.1 介绍下工厂设计模式A.1Q.2 这种设计模式有哪几种形式A.2Q.3 使用c写一个简单工厂的例子A.3Q.4 我…