数据结构小记【Python/C++版】——图结构篇

40张Python可视化图形 40张PyCharm基础图 1.熊猫基本花图 import pandas as pd import matplotlib.pyplot as plt # 数据集1:4组只有4个值: df = pd.DataFrame([8,8,1,2], index=['a', 'b', 'c', 'd'], columns=['x']) # 制定计划 df.plot(kind='pie', subplots=True, figsize=(8, 8)) # 显示情节 plt.show() 2.堆叠面积图的基线 阅读详情

一,基础概念

1.图的简介

图没有起始位置和终止位置,是由顶点和边组成的一种非线性数据结构。

2.图结构的常见概念

(先大概了解一下,后面可以结合图示对照看看): 

顶点(Vertex/Node):顶点又称节点,是图的基础部分。

边(Edge):两个顶点之间的连线。

权重(Weight):边上可以附带的权重大小,用来表示从一个顶点到另一个顶点的成本。

相邻(Adjacency):同一条边两端的顶点被称为相邻或者邻接。

路径(Path):由边连接的顶点组成的序列。

度(Degree):连接到一个顶点的边的数量。

入度(Indegree):按传入方向连接到顶点的有向边的总数。

出度(Outdegree):按传出方向连接到顶点的有向边的总数。

3.图的等式表示

图结构可以用等式表示:G=(V, E)。

G是图结构的抽象表示。

V是图中的顶点集合,一般用数组存储,所以V常见于顶点数组。

E是相邻顶点的集合,E中的元素也表示他们连接而成的边。例如E中的一个元素是(u, v),表示顶点u和顶点v连接成的边。如果是有方向的边,(u, v)和(v, u)表示的是不同方向的两条边,如果是无方向的边,则(u, v)和(v, u)表示的是同一条边。例如下图中的(1, 2)和(2, 1)表示的是相同的边。

该图有一组顶点V={1,2,3,4,5}和一组边E={(1,2),(1,3),(2,3),(2,4),(2,5),(3,5),(4,5)}。

二,常见的图结构分类

a.无向图

任意两个顶点之间的边不带方向。

b.有向图

任意两个顶点之间的边区分方向。

c.连通图

图数据结构的一个顶点与任何其他顶点之间存在可以到达的路径、

d.子图

顶点和边的组合是另一个图的子集

e.加权图

每条边都有一个权重,表示遍历该边的成本

三,图的常见表示方式

基于二维数组的表示方式——邻接矩阵(Adjacency Matrix)

基于链表的表示方式——邻接表(Adjacency List)

1.邻接矩阵

邻接矩阵用于显示哪些节点彼此相邻。

矩阵的行和列都是图的顶点列表,矩阵中不为0的地方表示顶点之间互相连接,即矩阵中不为0的地方表示边。

a.无向图的邻接矩阵
如果顶点a和顶点b之间存在边:AdjMatrix(A, B)=AdjMatrix(B, A)=1

b.有向图的邻接矩阵

如果存在顶点b到顶点a的边:AdjMatrix(B, A)=1

如果不存在顶点a到顶点b的边:AdjMatrix(A, B)=0

c.加权无向图的邻接矩阵

如果顶点a和顶点b之间存在边,且边的权重为3:AdjMatrix(A, B)=AdjMatrix(B, A)=3

2.邻接表

通俗说就是每个顶点专门有一个列表来记录自己有哪些邻居,这个列表常用链表结构来实现。此结构维护了两张表:

1.包含所有顶点的数组(主表)。

2.每个顶点单独对应的链表,此链表包含了与此顶点相邻的所有顶点集合。

a.无向图的邻接表

b.有向图的邻接表

c.加权有向图的邻接表

3.邻接表和邻接矩阵的对比

邻接矩阵的表示方式,简单直观且容易理解。其弱点在于,如果遇到了点很多而边很少的稀疏图,此时的矩阵包含大量的无效元素0,容易造成存储空间的浪费。

邻接表方便找任一顶点的所有邻接点,遇到稀疏图还能节省存储空间,其弱点在于,邻接表不方便检查任意两个顶点间是否存在边。

四,图的常见操作

由于邻接表的添加和删除操作比较容易,和链表结构的操作类似,此处主要展示邻接矩阵的添加和删除操作。

1.添加顶点

当添加一个顶点时,图形的大小会增加,从而使矩阵的行和列级别的大小加1。

2.删除顶点

如果删除的顶点出现在图中,则矩阵返回该顶点。如果删除的顶点没有出现在图中,则不做任何操作,函数直接返回。删除完以后,矩阵的行和列级别的大小减1。

3.两个顶点之间添加边

在添加边之前,AdjMatrix(C, B)=0,在添加边以后,AdjMatrix(C, B)=1。

4.两个顶点之间删除边

在删除边之前,AdjMatrix(D, D)=1,在删除边以后,AdjMatrix(D, D)=0。

5.遍历

广度优先遍历(BFS)

广度优先遍历也可以说是层次遍历,它是逐层对元素进行访问的。

广度优先遍历从图的任意一个起始位置开始,将图按照深度进行切分(类似于树结构的分层),在移动到下一个深度级别之前,先遍历当前深度级别的所有节点。

深度优先遍历(DFS)

深度优先是先任选一个出发点开始进行遍历,遍历的过程中,能继续往前移动就继续往前,如果不能就回退一步甚至再回退一步,然后从别的就近起点继续往前遍历。深度优先的遍历特点是,先选一条胡同走到底,走完了再跳到另外一条继续走到底。

两种遍历方式的对比

深度优先遍历,在遍历的过程中不存储所有的结点,占用空间小,但是遍历过程中有回溯操作(入栈/出栈),运行速度较慢。

广度优先遍历,在遍历的过程中存储所有的结点,占用空间大,但是无回溯操作,运行速度较快。

五,代码实例

1.邻接矩阵的代码样例

场景:

Python实现:

class Graph(object):
    def __init__(self, size):
        self.adjMatrix = []
        for i in range(size):
            self.adjMatrix.append([0 for i in range(size)])
        self.size = size

    def add_edge(self, v1, v2):
        if v1 == v2:
            print("Same vertex %d and %d" % (v1, v2))
        self.adjMatrix[v1][v2] = 1
        self.adjMatrix[v2][v1] = 1

    def remove_edge(self, v1, v2):
        if self.adjMatrix[v1][v2] == 0:
            print("No edge between %d and %d" % (v1, v2))
            return
        self.adjMatrix[v1][v2] = 0
        self.adjMatrix[v2][v1] = 0

    def __len__(self):
        return self.size

    def print_matrix(self):
        for row in self.adjMatrix:
            tmp = []
            for val in row:
                tmp.append(val)
            print(tmp)

def main():
    g = Graph(4)
    g.add_edge(0, 1)
    g.add_edge(0, 2)
    g.add_edge(1, 2)
    g.add_edge(0, 3)

    g.print_matrix()

if __name__ == '__main__':
    main()

运行结果:

[0, 1, 1, 1]
[1, 0, 1, 0]
[1, 1, 0, 0]
[1, 0, 0, 0]

C++实现:

#include <iostream>
using namespace std;
class Graph {
private:
    bool** adjMatrix;
    int numVertices;
public:
    Graph(int numVertices) {
        this->numVertices = numVertices;
        adjMatrix = new bool* [numVertices];
        for (int i = 0; i < numVertices; i++) {
            adjMatrix[i] = new bool[numVertices];
            for (int j = 0; j < numVertices; j++)
                adjMatrix[i][j] = false;
        }
    }

    void addEdge(int i, int j) {
        adjMatrix[i][j] = true;
        adjMatrix[j][i] = true;
    }

    void removeEdge(int i, int j) {
        adjMatrix[i][j] = false;
        adjMatrix[j][i] = false;
    }

    void toString() {
        for (int i = 0; i < numVertices; i++) {
            cout << i << " : ";
            for (int j = 0; j < numVertices; j++)
                cout << adjMatrix[i][j] << " ";
            cout << "\n";
        }
    }
    ~Graph() {
        for (int i = 0; i < numVertices; i++)
            delete[] adjMatrix[i];
        delete[] adjMatrix;
    }
};
int main() {
    Graph g(4);
    g.addEdge(0, 1);
    g.addEdge(0, 2);
    g.addEdge(1, 2);
    g.addEdge(0, 3);
    g.toString();
}

运行结果:

0 : 0 1 1 1
1 : 1 0 1 0
2 : 1 1 0 0
3 : 1 0 0 0

2.邻接表的代码样例

场景:

6个顶点,9条边组成的加权有向图

Python实现:

Python版的邻接矩阵,最简单的实现方式是为每个顶点都维护一个字典,字典的键是顶点,值是权重。

Graph类存储包含所有顶点的主列表。

Vertex类表示图中的每一个顶点,Vertex 使用字典 connectedTo 来记录与其相连的顶点,以及每一条边的权重。

class Graph:
    def __init__(self):
        self.vertList = {}
        self.numVertices = 0
    def addVertex(self, key):
        self.numVertices = self.numVertices + 1
        newVertex = Vertex(key)
        self.vertList[key] = newVertex
        return newVertex
    def getVertex(self, n):
        if n in self.vertList:
            return self.vertList[n]
        else:
            return None
    def __contains__(self, n):
        return n in self.vertList
    #向图中添加带权重的边
    def addEdge(self, f, t, cost=0):
        if f not in self.vertList:
            nv = self.addVertex(f)
        if t not in self.vertList:
            nv = self.addVertex(t)
        self.vertList[f].addNeighbor(self.vertList[t], cost)
    def getVertices(self):
        return self.vertList.keys()
    #魔法函数,遍历图中的所有顶点对象
    def __iter__(self):
        return iter(self.vertList.values())

class Vertex:
    def __init__(self, key):
        self.id = key
        self.connectedTo = {}
    def addNeighbor(self, nbr, weight=0):
        self.connectedTo[nbr] = weight
    def __str__(self):
        return str(self.id) + ' connectedTo: ' + str([x.id for x in self.connectedTo])
    #返回邻接表中的所有顶点
    def getConnections(self):
        return self.connectedTo.keys()
    def getId(self):
        return self.id
    #返回指定顶点之间边上的权重
    def getWeight(self, nbr):
        return self.connectedTo[nbr]

if __name__ == '__main__':
    g = Graph()
    for i in range(6):
        g.addVertex(i)
    print("打印顶点对象: ", g.vertList)
    g.addEdge(0, 1, 5)
    g.addEdge(0, 5, 2)
    g.addEdge(1, 2, 4)
    g.addEdge(2, 3, 9)
    g.addEdge(3, 4, 7)
    g.addEdge(3, 5, 3)
    g.addEdge(4, 0, 1)
    g.addEdge(5, 4, 8)
    g.addEdge(5, 2, 1)
    for v in g:
        for w in v.getConnections():
            #遍历邻接表,返回顶点和邻接的顶点,以及边的权重
            print("( %s , %s : %s)" % (v.getId(), w.getId(), v.getWeight(w)))

运行结果:

打印顶点对象:  {0: <__main__.Vertex object at 0x0000013A5A55B358>,
1: <__main__.Vertex object at 0x0000013A5A55B390>,
2: <__main__.Vertex object at 0x0000013A5A55B3C8>,
3: <__main__.Vertex object at 0x0000013A5A55B400>,
4: <__main__.Vertex object at 0x0000013A5A55B438>,
5: <__main__.Vertex object at 0x0000013A5A55B470>}
( 0 , 1 : 5)
( 0 , 5 : 2)
( 1 , 2 : 4)
( 2 , 3 : 9)
( 3 , 4 : 7)
( 3 , 5 : 3)
( 4 , 0 : 1)
( 5 , 4 : 8)
( 5 , 2 : 1)

C++实现:

#include <iostream>
using namespace std;

struct adjNode {
    int val, cost;
    adjNode* next;
};
struct graphEdge {
    int start_ver, end_ver, weight;
};
class DiaGraph {
    adjNode* getAdjListNode(int value, int weight, adjNode* head) {
        adjNode* newNode = new adjNode;
        newNode->val = value;
        newNode->cost = weight;
        newNode->next = head;  
        return newNode;
    }
    int N;  
public:
    adjNode** head;                
    DiaGraph(graphEdge edges[], int n, int N) {
        head = new adjNode * [N]();
        this->N = N;
        for (int i = 0; i < N; ++i)
            head[i] = nullptr;
        for (unsigned i = 0; i < n; i++) {
            int start_ver = edges[i].start_ver;
            int end_ver = edges[i].end_ver;
            int weight = edges[i].weight;
            adjNode* newNode = getAdjListNode(end_ver, weight, head[start_ver]);
            head[start_ver] = newNode;
        }
    }
    ~DiaGraph() {
        for (int i = 0; i < N; i++)
            delete[] head[i];
        delete[] head;
    }
};

void display_AdjList(adjNode* ptr, int i)
{
    while (ptr != nullptr) {
        cout << "(" << i << ", " << ptr->val
            << ", " << ptr->cost << ") ";
        ptr = ptr->next;
    }
    cout << endl;
}

int main()
{
    // graph edges array.
    graphEdge edges[] = {
    // (x, y, w) -> edge from x to y with weight w
    {0, 1, 5},
    {0, 5, 2},
    {1, 2, 4},
    {2, 3, 9},
    {3, 4, 7},
    {3, 5, 3},
    {4, 0, 1},
    {5, 4, 8},
    {5, 2, 1}
    };
    int N = 6;  // Number of vertices in the graph                                      
    int n = sizeof(edges) / sizeof(edges[0]); // calculate number of edges
    DiaGraph diagraph(edges, n, N);
    cout << "Graph adjacency list " << endl << "(start_vertex, end_vertex, weight):"  << endl;
    for (int i = 0; i < N; i++)
    {
        display_AdjList(diagraph.head[i], i);
    }
    return 0;
}

运行结果:

Graph adjacency list
(start_vertex, end_vertex, weight):
(0, 5, 2) (0, 1, 5)
(1, 2, 4)
(2, 3, 9)
(3, 5, 3) (3, 4, 7)
(4, 0, 1)
(5, 2, 1) (5, 4, 8)

3.广度优先的代码样例

场景: 

遍历顺序: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6

Python实现:

class Graph:
    adj = []
    def __init__(self, v, e):
        self.v = v
        self.e = e
        Graph.adj = [[0 for i in range(v)]
                     for j in range(v)]

    def addEdge(self, start, e):
        Graph.adj[start][e] = 1
        Graph.adj[e][start] = 1

    def BFS(self, start):
        visited = [False] * self.v
        q = [start]

        # Set source as visited
        visited[start] = True

        while q:
            vis = q[0]

            # Print current node
            print(vis, end=' ')
            q.pop(0)

            # For every adjacent vertex to
            # the current vertex
            for i in range(self.v):
                if (Graph.adj[vis][i] == 1 and
                        (not visited[i])):
                    # Push the adjacent node
                    # in the queue
                    q.append(i)
                    visited[i] = True

v, e = 7, 7

#Create the graph
G = Graph(v, e)
G.addEdge(0, 1)
G.addEdge(0, 2)
G.addEdge(1, 3)
G.addEdge(1, 4)
G.addEdge(2, 5)
G.addEdge(6, 3)
G.addEdge(6, 4)

G.BFS(0)

运行结果:

0 1 2 3 4 5 6

C++实现:

#include<bits/stdc++.h>
using namespace std;
vector<vector<int>> adj;

void addEdge(int x, int y)
{
       adj[x][y] = 1;
       adj[y][x] = 1;
}

void bfs(int start)
{
       vector<bool> visited(adj.size(), false);
       vector<int> q;
       q.push_back(start);
       // Set source as visited
       visited[start] = true;
       int vis;
       while (!q.empty()) {
              vis = q[0];
              // Print the current node
              cout << vis << " ";
              q.erase(q.begin());
              // For every adjacent vertex to the current vertex
              for (int i = 0; i < adj[vis].size(); i++) {
                      if (adj[vis][i] == 1 && (!visited[i])) {
                             // Push the adjacent node to the queue
                             q.push_back(i);
                             // Set
                             visited[i] = true;
                      }
              }
       }
}

int main()
{
       // number of vertices
       int v = 7;
       // adjacency matrix
       adj = vector<vector<int>>(v, vector<int>(v, 0));
       addEdge(0, 1);
       addEdge(0, 2);
       addEdge(1, 3);
       addEdge(1, 4);
       addEdge(2, 5);
       addEdge(6, 3);
       addEdge(6, 4);

       bfs(0);
}

运行结果:

0 1 2 3 4 5 6

4.深度优先的代码样例

场景:

遍历顺序:0 -> 1 -> 3 -> 2

Python实现:

class Graph:
    adj = []

    def __init__(self, v, e):
        self.v = v
        self.e = e
        Graph.adj = [[0 for i in range(v)]
                     for j in range(v)]

    def addEdge(self, start, e):
        Graph.adj[start][e] = 1
        Graph.adj[e][start] = 1

    def DFS(self, start, visited):
        print(start, end=' ')
        visited[start] = True
        for i in range(self.v):
            if (Graph.adj[start][i] == 1 and
                    (not visited[i])):
                self.DFS(i, visited)

v, e = 5, 4

G = Graph(v, e)
G.addEdge(0, 1)
G.addEdge(0, 2)
G.addEdge(1, 3)

G.DFS(0, visited);

运行结果:

0 1 3 2

C++实现:

#include <bits/stdc++.h>
using namespace std;

vector<vector<int> > adj;
void addEdge(int x, int y)
{
       adj[x][y] = 1;
       adj[y][x] = 1;
}
void dfs(int start, vector<bool>& visited)
{
       // Print the current node
       cout << start << " ";
       // Set current node as visited
       visited[start] = true;
       // For every node of the graph
       for (int i = 0; i < adj[start].size(); i++) {
              // If some node is adjacent to the current node
              // and it has not already been visited
              if (adj[start][i] == 1 && (!visited[i])) {
                      dfs(i, visited);
              }
       }
}
int main()
{
       // number of vertices
       int v = 5;
       // number of edges
       int e = 4;
       // adjacency matrix
       adj = vector<vector<int> >(v, vector<int>(v, 0));
       addEdge(0, 1);
       addEdge(0, 2);
       addEdge(1, 3);
       vector<bool> visited(v, false);

       dfs(0, visited);
}

运行结果:

0 1 3 2

六,参考阅读

《Problem Solving with Algorithms and Data Structures Using Python, Second Edition》

https://www.simplilearn.com/tutorials/data-structure-tutorial/graphs-in-data-structure

https://www.softwaretestinghelp.com/graph-implementation-cpp/

https://www.programiz.com/dsa/graph-adjacency-matrix

https://www.geeksforgeeks.org/implementation-of-dfs-using-adjacency-matrix/

https://www.geeksforgeeks.org/implementation-of-bfs-using-adjacency-matrix/

https://www.programiz.com/dsa/graph-adjacency-matrix

Python 算法基础篇:图的基本概念和表示方法 图是计算机科学中的一种重要数据结构,它是由节点和边组成的集合,用于表示物体之间的关系。本篇博客将重点介绍图的基本概念和表示方法,包括有向图、无向图、带权图的概念,以及邻接矩阵和邻接表两种常用的图表示方法,并通过实例代码演示图的创建和基本操作,每行代码都配有详细的注释。 阅读详情

相关推荐

Python高级数据结构——图论算法(Graph Algorithms)

图论算法是解决与图相关问题的重要工具,它涵盖了图的表示、遍历、最短路径、最小生成树等多个方面。在Python中,可以使用字典等数据结构来表示图,通过深度优先搜索、广度优先搜索、Dijkstra算法、Prim算法等实现图论算法。理解图论算法的基本概念、实现方式和应用场景,将有助于更好地应用图论算法解决实际问题。

Echo_Wish 1862

python数据结构之图

入门小菜鸟,希望像做笔记记录自己学的东西,也希望能帮助到同样入门的人,更希望大佬们帮忙纠错啦~侵权立删。 一、图的相关概念 1、图 表示多对多的关系 一组顶点,通常用V(Vertex)表示顶点集合 一组边,通常用E(Edge)表示边的集合,边是顶点对,分为有向边和无向边 下图即为图。 2、无向图和有向图 ????无向图:边没有方向的图。(即从A可以直接到B,B也可以直接到A) ????有向图:边有方向的图。(即从A可以直接到B,但B不能直接到A) ????入度:以顶点A为头的

tt丫的博客 4213

C8T6和ZET6选型更换过程中出现.\Obj\Project.sct(7): error: L6235E: More than one section matches selector - cann

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、问题原因二、解决方法三、现象总结 前言 又一件离谱的事情发生了,我之前转换过程中没有发生的错误,今天拿出来程序重新编译了一下,结果他奶奶滴一个新的错误出现了,而且我还完全不知道是什么原因导致的,先上图: 一、问题原因 之前我已经尝试过更换芯片选型,但是没有出现此类问题,今天更改的时候发现了,我还以为是个偶然错误,结果换来换去,还是有这个问题,那我之前说c8t6的程序更改成zet6上跑只需改芯片选型和宏定义岂不是啪啪打.

wx18045623090的博客 1489

Python 中的图:图的存储结构

文章目录1 什么是图2 图的三种存储方式2.1 边列表(List of Edges)2.1.1 原理2.1.2 Python 实现 1 什么是图   图是一种数据结构,可用于对对象之间的层次结构和关系进行建模。它由一组节点和一组边组成。节点表示单个对象,而边表示这些对象之间的关系。注意:可能在不同的文献中节点也被称作顶点,它们指同一个意思。   如果图中的边可以通过双向遍历,则是无向图(undirected),如果只能通过一个方向进行遍历,则是有向图(undirected)。 并非图的所有节点都需要与其他

weixin_53598445的博客 6194

Docker 与容器技术的未来:从 OCI 标准到 eBPF 的演进

OCI 的核心目标是创建一个开放的、厂商中立的容器技术标准。这意味着,只要一个容器镜像符合 OCI 镜像格式规范,它就可以在任何符合 OCI 运行时规范的容器运行时上运行。eBPF 是一种革命性的技术,它允许在 Linux 内核中安全地运行沙盒程序,而无需修改内核源代码或加载内核模块。这些程序可以注册到内核中的各种事件点(如网络包到达、系统调用、函数调用/返回),并在事件发生时执行自定义逻辑。核心思想是:在不将数据复制到用户空间的情况下,程序可以直接在内核中处理数据,极大地提高了效率和性能。

专栏 1383

从OAuth到DID:Web4.0身份验证协议的技术演进图谱

在数字身份体系从Web2.0向Web4.0跨越的进程中,身份验证协议正经历着从中心化授权到自主主权的范式转移。本文通过对比OAuth 2.0、OpenID Connect等传统方案与W3C DID、ION等去中心化协议的技术架构,揭示身份验证技术在性能、安全、隐私三大维度的代际差异。基于对GitHub、欧盟数字身份钱包等典型系统的实测数据分析,量化评估中心化授权服务器的单点故障风险与DID链上验证的吞吐量瓶颈。结合零知识证明、分布式密钥管理等前沿技术,为开发者提供面向Web4.0的渐进式身份架构迁移策略。

水务人 834

数据结构小记【Python/C++版】——队列篇

数据结构基础

程序员与背包客_CoderZ 833

CS之攻击菜单详解-后门生成与上线

能够生成如HTA文档、office宏、payload生成器、exe程序。 windows可执行程序exe 可以看到能生成两种windows可执行程序,其分别代表stage分阶段和unstage(stageless)不分阶段。传送门 ——>Cobalt Strike中payload的stage与unstage区别 选择监听器后,按需生成不同类型的exe 然后在目标机器运行即可上线 payload生成器 选择生成如下类型的后门 ——>https://che...

渗透之路,攻防之间皆学问 6808

数据结构小记【Python/C++版】——栈篇

数据结构基础

程序员与背包客_CoderZ 1113

Android16 3576 u盘固件升级功能添加

1.在u-boot/drivers/power/pmic/rk8xx.c。这里是读取power键的寄存器判断长短按。

tzj1058756809的博客 575

Qt | linux+openCV+Qt6.5.3环境搭建成功版(带例子)

opencv安装 Qt 实战举例

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 1885

数据结构小记【Python/C++版】——堆结构篇

数据结构基础

程序员与背包客_CoderZ 928

基于YOLOv8的智能肿瘤检测系统:从图像到诊断的深度学习应用——含代码和论文

本文提出了一种基于YOLOv8深度学习的智能肿瘤检测系统,用于医学影像(CT/MRI/X光)的自动分析与诊断。针对传统人工阅片效率低、主观性强的问题,系统采用最新的YOLOv8目标检测算法,通过改进的C2F骨干网络、Anchor-Free检测头和解耦头等创新设计,实现高效精准的肿瘤定位。文章详细阐述了模型架构、数据处理流程、训练优化方法及PyQt5用户界面开发,为临床提供可靠的AI辅助诊断工具。实验结果表明,该系统在速度和准确率上达到良好平衡,有望提升肿瘤早期筛查效率。

FJN110的博客 199

数据结构小记【Python/C++版】——散列表篇

数据结构基础

程序员与背包客_CoderZ 1623

Xilinx FPGA平台GTX简易使用教程(五)GTX收发测试及示例工程介绍

GTX IP配置完了,你不得搞个回环测试一番?

数字IC/FPGA杂货铺,找一找,或许有你想要的~ 1万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

数据结构小记【Python/C++版】——链表篇

数据结构基础

程序员与背包客_CoderZ 1248

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

数据结构小记【Python/C++版】——BST树篇

数据结构基础

程序员与背包客_CoderZ 1213

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

数据结构小记【Python/C++版】——树与二叉树篇

数据结构基础

程序员与背包客_CoderZ 866

数据结构小记【Python/C++版】——AVL树篇

数据结构基础

程序员与背包客_CoderZ 1060

数据结构小记【Python/C++版】——B树篇

数据结构基础

程序员与背包客_CoderZ 771

c++面试八股小记1

例如,全局变量或静态变量持有的内存。派生类在多继承时,由多个虚表指针,对某个基类虚函数重写时,对应基类的虚表中的虚函数指针会被更新,如果有新虚函数,会在第一个虚表后增加虚函数地址。保证安全和稳定,将普通程序限制在了用户态下,不允许直接访问硬件和io等资源,限制了cpu的权限,避免了用户的误操作导致资源损坏。模板:写一些与类型无关的代码,编译器在编译时生成模板的带类型的实例,同时也确定了调用的具体代码。函数重载:函数名相同,参数列表不同(类型,数量,顺序),编译器根据提供的实参决定调用哪个函数。

weixin_62692110的博客 1256

C++小记

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34072458的博客 92

头条面试小记

基础小面: 1.python中常用的数据结构有哪些? 2.列表和元组的区别?还有什么区别? 3.固件安全?啥是固件?固件是硬件吗?和软件有啥区别?你们搞这个用来做啥的? 我刚说固件是底层软件,她接上话是不是芯片,我说芯片里面也有,还有路由器、交换机、防火墙、打印机、手机、网络摄像头、工业机器人、PLC等,还没等我说一半,就打断了我。说她不懂。 4.mongodb和mysql区别和...

果冻先生的专栏 515

opencv python 创建灰度图_Opencv的Mat内容小记

1.Mat是什么Mat是一种图像容器,是二维向量,灰度图的Mat一般存放<uchar>类型,RGB彩色图像一般存放<Vec3b>类型。单通道灰度图数据存放样式:RGB三通道彩色图存放形式不同,每列并列存放通道数量的子列(注意通道数量反转为了BGR):通常情况下Mat的每一行是连续存放的,也就是在内存上图像的所有数据存放成一行,在用指针访问时可以提供很大方便。可以用 isCo...

weixin_33588445的博客 1886

每周小记——JVM

本文剖析JVM核心机制:详述内存模型(堆、方法区、栈)及垃圾回收算法(标记-清除/复制/压缩)、分代策略与GC类型(Minor/Major/FullGC);解析类加载机制(双亲委派模型、加载/链接/初始化过程及三类加载器差异);阐述执行引擎(JIT编译、热点探测、逃逸分析);对比现代收集器(G1/ZGC/Shenandoah)及CMS优劣;探讨性能调优关键(吞吐量与延迟平衡、内存分配策略)。为Java性能优化提供理论支撑。

weixin_57655687的博客 1583

python中的弱引用weakref

今天在看python cookbook时遇到一个有趣的问题,特作小记,有知道这个问题原因的兄弟请不吝赐教. 首先,python中的垃圾回收机制是简单的基于引用计数规则的,这一点很好理解,当一个实例对象长时间没人使用时,gc就会自动把它回收掉。不知道那些技术牛的程序员如何看待Python、Java这些自动内存管理的编程语言,但我从C——C++——Python的路线走过来,还是喜欢自己管理内存,手动...

遥远的她 6960
上一篇: 数据结构小记【Python/C++版】——链表篇
下一篇: 数据结构小记【Python/C++版】——队列篇
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员与背包客_CoderZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值