图——基本的图算法(一)图的存储结构

1. 图的存储结构概述

对于图G=(V, E)来说,可以有两种标准的表示方法,一个是邻接矩阵,另一个是邻接链表,这两种方法都可以表示有向图和无向图。除此之外,图的存储结构还有十字链表邻接多重表边集数组等。

2. 图的各种存储结构及实现

2.1 邻接矩阵

(1)总体思路
邻接矩阵是用两个数组来表示一个图:一个一维数组用来存储每个顶点的信息;一个二维数组(即邻接矩阵)用来存储图中的边或弧信息。对于图G =(V, E)来说,邻接矩阵matrix是一个|V|*|V|的方阵,假设1 <= i, j <= |V|,如果matrix[i][j] == 0,则表示顶点i和顶点j之间没有边相连;反之,如果matrix[i][j] != 0,则表示表示顶点i和顶点j之间有边相连,且matrix[i][j]存储的值即为该边的权重。
(2)具体实现
A. 数据结构
首先明确,一个图结构中包含两个数组,一个顶点表和一个用来存储图中边或弧信息的二维数组:
顶点表
用来存储图中顶点信息,是一个一维数组,顶点信息可以自定义,此处定义为int类型:

#define Maximum 1000
typedef int VexType;VexType vertexlist[Maximum];

邻接矩阵
是一个二维矩阵,大小为|V|*|V|,用来存储图中边或弧信息,其中二维矩阵的类型(即边的权值类型)可以自定义,此处定义为int:

#define Maximum 1000
typedef int MatrixType;MatrixType matrix[Maximum][Maximum];


综合起来,图的数据结构为:

#define Maximum 1000
typedef int VexType;
typedef int MatrixType;typedef struct GraphAdjMatrix {VexType vertexlist[Maximum];MatrixType matrix[Maximum][Maximum];int vertexnumber;int edgenumber;
};

B. 图的创建
图的创建分为顶点表初始化和邻接矩阵初始化两步:
a. 顶点表初始化:

CreateVertexlist() {int i, j, k;cout<<"Please enter the number of vertexes"<<endl;cin>>i;G->vertexnumber = i;cout<<"Please enter the data of each vertex in term"<<endl;for(j=0; j<i; j++) {cin>>k;G->vertexlist[j] = k;}}

b. 邻接矩阵初始化

 CreateMatrix() {int i, j, k, s, e, w;cout<<"Please enter the number of edges"<<endl;cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w;G->matrix[s][e] = w;}}

c. 图的创建

CreateGraph() {CreateVertexlist();CreateMatrix();}

C. 针对有向图和无向图分别写一个类,对上述内容进行封装:
a. class UndirectGraph(无向图)

#define Maximum 1000
typedef int VexType;
typedef int MatrixType;typedef struct GraphAdjMatrix {VexType vertexlist[Maximum];MatrixType matrix[Maximum][Maximum];int vertexnumber;int edgenumber;
};class UndirectGraph {
public:GraphAdjMatrix* G;UndirectGraph() {G = (GraphAdjMatrix*)malloc(sizeof(GraphAdjMatrix));memset(G->vertexlist, 0, sizeof(G->vertexlist));memset(G->matrix, 0, sizeof(G->matrix));}CreateVertexlist() {int i, j, k;cout<<"Please enter the number of vertexes"<<endl;cin>>i;G->vertexnumber = i;cout<<"Please enter the data of each vertex in term"<<endl;for(j=0; j<i; j++) {cin>>k;G->vertexlist[j] = k;}}CreateMatrix() {int i, j, k, s, e, w;cout<<"Please enter the number of edges"<<endl;cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w;G->matrix[s][e] = w;G->matrix[e][s] = w;}}CreateGraph() {CreateVertexlist();CreateMatrix();}};

b. class DirectGraph(无向图)

#define Maximum 1000
typedef int VexType;
typedef int MatrixType;typedef struct GraphAdjMatrix {VexType vertexlist[Maximum];MatrixType matrix[Maximum][Maximum];int vertexnumber;int edgenumber;
};class DirectGraph {
public:GraphAdjMatrix* G;DirectGraph() {G = (GraphAdjMatrix*)malloc(sizeof(GraphAdjMatrix));memset(G->vertexlist, 0, sizeof(G->vertexlist));memset(G->matrix, 0, sizeof(G->matrix));}CreateVertexlist() {int i, j, k;cout<<"Please enter the number of vertexes"<<endl;cin>>i;G->vertexnumber = i;cout<<"Please enter the data of each vertex in term"<<endl;for(j=0; j<i; j++) {cin>>k;G->vertexlist[j] = k;}}CreateMatrix() {int i, j, k, s, e, w;cout<<"Please enter the number of edges"<<endl;cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w; //s:边的起点  e:边的终点  w:边的权值G->matrix[s][e] = w;}}CreateGraph() {CreateVertexlist();CreateMatrix();}};

2.2 邻接链表

(1)总体思路
邻接链表是一种不错的图存储结构,由于它在表示稀疏图的时候非常紧凑而成为通常的选择。对于图G =(V, E)来说,在其邻接链表表示中,每个结点对应一条链表,因此这个图里有V条链表。假设用一个V维的数组Adj来存储这V条链表,且Adj[i]表示的是结点i对应的链表,那么Adj[i]这条链表里存储的就是所有与节点i之间有边相连的结点,即与结点i相邻的结点。举个例子:

上图中的(a)是一个无向图,(b)是它的邻接链表表示,可以看到图中有5个结点,每个结点对应一条链表,链表中的结点都是与该节点相邻的,例如结点1的链表中有结点2和结点5,它们都与结点1相邻。

(2)具体实现
A. 数据结构
首先要明确,一个图包含了一个顶点表,而顶点表里的每一项又包含一个边表
顶点表:该表包含了图里的所有顶点,顶点表的每一项用于存储该顶点的属性(例如该结点对应的值),以及指向其边表的第一个结点的指针。
边表:某个顶点的边表存放了与其相邻的结点。

明确上述两个结构后,就具体介绍这两个表里每一项的数据结构:
边表结点:边表里的每一项叫做边表结点,它包含adjId、weight和next两个区域。其中,adjId存储的是某顶点的邻接点在顶点表中的下标值,weight存储了这条边的权重,而next则是一个指向边表中下一个结点的指针。具体代码:

typedef struct EdgeListNode{int adjId;int weight;EdgeListNode* next;
};

顶点表结点:顶点表里的每一项叫顶点表结点,它包含两个区域,分别是该顶点的属性(此处令它为一个int类型的值)和指向其边表第一个结点的指针:

typedef struct VertexListNode{int data;EdgeListNode* firstadj;
};

那么,一个图的数据结构中就可以包含顶点数、边数、一个顶点表:

#define Maximum 1000 //预设一个边表大小的最大值
typedef struct GraphAdjList{int vertexnumber;int edgenumber;VertexListNode vertextlist[Maximum];
};

对上述数据结构进行统一整理:

#define Maximum 1000typedef struct EdgeListNode{int adjId;int weight;EdgeListNode* next;
};typedef struct VertexListNode{int data;EdgeListNode* firstadj;
};typedef struct GraphAdjList{int vertexnumber;int edgenumber;VertexListNode vertextlist[Maximum];
};

B. 图的创建
定义好图的数据结构之后,就要开始进行图的创建了。创建图的过程分为两步,先初始化图里的顶点表,然后再来创建边表:
a. 顶点表初始化:

void VertexListInit() {int i, j, k;cout<<"Please enter the number of vertexes"<<endl; //输入顶点个数cin>>i;G->vertexnumber = i; //设置图结构里的顶点个数cout<<"Please enter the data of each vertex in term"<<endl;for(j=0; j<i; j++) { //依此输入每个顶点,且该顶点再顶点表中对应的下标为icin>>k;k = G->vertextlist[i].data;G->vertextlist[i].firstadj = NULL; //将其指向边表第一个结点的指针置为空}}

b. 创建边表
这里要注意区别有向图和无向图。有向图每增加一条边只需在该边出口顶点对应的边表里添加一个边表结点,而无向图需要在边的两个顶点对应的边表里进行添加。
无向图:

void EdgeListCreate() {int i, j, s, e, w;EdgeListNode* edge;cout<<"Please enter the number of edges"<<endl; //输入边的条数cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w; //s:边的起点  e:边的终点  w:边的权值edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));edge->adjId = e;edge->weight = w;/*此处采用头插法,即每次往边表的头部插入新结点*/edge->next = G->vertextlist[s].firstadj;G->vertextlist[s].firstadj = edge;edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));edge->adjId = s;edge->weight = w;edge->next = G->vertextlist[e].firstadj;G->vertextlist[e].firstadj = edge;}}

有向图:

void EdgeListCreate() {int i, j, s, e, w;EdgeListNode* edge;cout<<"Please enter the number of edges"<<endl; //输入边的条数cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w; //s:边的起点  e:边的终点  w:边的权重edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));edge->adjId = e;edge->weight = w;/*此处采用头插法,即每次往边表的头部插入新结点*/edge->next = G->vertextlist[s].firstadj;G->vertextlist[s].firstadj = edge;}}

c. 综合起来,图的创建:

void CreateGraphAdjList() {VertexListInit();EdgeListCreate();}

C. 针对有向图和无向图分别写一个类,对上述内容进行封装:
a. class UndirectGraph(无向图)

#define Maximum 1000typedef struct EdgeListNode{int adjId;int weight;EdgeListNode* next;
};typedef struct VertexListNode{int data;EdgeListNode* firstadj;
};typedef struct GraphAdjList{int vertexnumber;int edgenumber;VertexListNode vertextlist[Maximum];
};class UndirectGraph {
public:GraphAdjList* G;UndirectGraph() {G = (GraphAdjList*)malloc(sizeof(GraphAdjList));}void VertexListInit() {int i, j, k;cout<<"Please enter the number of vertexes"<<endl;cin>>i;G->vertexnumber = i;cout<<"Please enter the data of each vertex in term"<<endl;for(j=0; j<i; j++) {cin>>k;G->vertextlist[i].data = k;G->vertextlist[i].firstadj = NULL;}}void EdgeListCreate() {int i, j, s, e, w;EdgeListNode* edge;cout<<"Please enter the number of edges"<<endl;cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w;edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));edge->adjId = e;edge->weight = w;edge->next = G->vertextlist[s].firstadj;G->vertextlist[s].firstadj = edge;edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));edge->adjId = s;edge->weight = w;edge->next = G->vertextlist[e].firstadj;G->vertextlist[e].firstadj = edge;}}void CreateGraphAdjList() {VertexListInit();EdgeListCreate();}};

b. class DirectGraph(有向图)

#define Maximum 1000typedef struct EdgeListNode{int adjId;int weight;EdgeListNode* next;
};typedef struct VertexListNode{int data;EdgeListNode* firstadj;
};typedef struct GraphAdjList{int vertexnumber;int edgenumber;VertexListNode vertextlist[Maximum];
};class DirectGraph {
public:GraphAdjList* G;DirectGraph() {G = (GraphAdjList*)malloc(sizeof(GraphAdjList));}void VertexListInit() {int i, j, k;cout<<"Please enter the number of vertexes"<<endl;cin>>i;G->vertexnumber = i;cout<<"Please enter the data of each vertex in term"<<endl;for(j=0; j<i; j++) {cin>>k;G->vertextlist[i].data = k;G->vertextlist[i].firstadj = NULL;}}void EdgeListCreate() {int i, j, s, e, w;EdgeListNode* edge;cout<<"Please enter the number of edges"<<endl;cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w;edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));edge->adjId = e;edge->weight = w;edge->next = G->vertextlist[s].firstadj;G->vertextlist[s].firstadj = edge;}}void CreateGraphAdjList() {VertexListInit();EdgeListCreate();}};

逆邻接链表(补充)

逆邻接链表一个图的逆邻接链表,即对每个顶点Vi都建立一个以Vi为入口结点的链表),例如下面这个例子,图中以顶点V0为入口结点的弧有(V1,V0)和(V2,V0),因此顶点V0的边表就包含了V1和V2。

2.3 十字链表(针对有向图邻接链表的优化)

(1)总体思路
对于有向图而言,邻接链表的缺陷是要查询某个顶点的入度时需要遍历整个链表,而逆邻接链表在查询某个顶点的出度时要遍历整个链表。为了解决这些问题,十字链表将邻接链表和逆邻接链表综合了起来,其基本思想就是在邻接链表的出边表的基础上,增加一个入边表。

(2)具体实现
A. 数据结构
a. 顶点表中结点的结构:

typedef struct VertexListNode{int data;EdgeListNode* firstadjin;EdgeListNode* firstadjout;
};

其中,firstadjin表示入边表头指针,指向该顶点的入边表的第一个结点;firstadjout表示出边表头指针,指向该顶点的出边表的第一个结点,这个和邻接链表里的是一样的。

b. 边表中结点的结构:

typedef struct EdgeListNode{int tailvex;int headvex;int weight;EdgeListNode* headlink;EdgeListNode* taillink;
};

其中,tailvex是指弧起点在顶点表中的下标;headvex是指弧终点在顶点表中的下标;weight表示这条边的权值;headlink是指弧终点的入边表指针域,指向弧终点的入边表里的下一个结点,即指向与该边终点相同的下一条边;taillink是弧起点的出边表指针域,指向弧起点的出边表里的下一个结点,即指向与该边起点相同的下一条边。

c. 用十字链表表示的图结构:

typedef struct GraphOthList{int vertexnumber;int edgenumber;VertexListNode vertextlist[Maximum];
};

B. 图的创建
a. 初始化顶点表

void VertexListInit() {int i, j, k;cout<<"Please enter the number of vertexes"<<endl;G->vertexnumber = i;cout<<"Please enter the data of each vertex in term"<<endl;for(j=0; j<i; j++) {cin>>k;k = G->vertextlist[j].data;G->vertextlist[j].firstadjin = NULL;G->vertextlist[j].firstadjout = NULL;}}

b. 初始化边表

  void EdgeListCreate() {int i, j, s, e, w;cout<<"Please enter the number of edges"<<endl; cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w;  //s:弧的起点  e:弧的终点  w:弧的权值EdgeListNode* edge;edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));edge->headvex = s; edge->tailvex = e;//指向弧起点的出边表中的下一个结点,采用头插法edge->taillink = G->vertextlist[s].firstadjout;G->vertextlist[s].firstadjout = edge;//指向弧终点的入边表中的下一个结点,采用头插法edge->headlink = G->vertextlist[e].firstadjin;G->vertextlist[e].firstadjin = edge;}}

c. 综合起来,图的创建:

void CreateGraph() {VertexListInit();EdgeListCreate();}

C. 把上述内容封装起来,创建一个十字链表表示图的类:

#define Maximum 1000typedef struct EdgeListNode{int tailvex;int headvex;EdgeListNode* headlink;EdgeListNode* taillink;
};typedef struct VertexListNode{int data;EdgeListNode* firstadjin;EdgeListNode* firstadjout;
};typedef struct GraphOthList{int vertexnumber;int edgenumber;VertexListNode vertextlist[Maximum];
};class DirectGraph {
public:GraphOthList* G;DirectGraph() {G = (GraphOthList*)malloc(sizeof(GraphOthList));}void VertexListInit() {int i, j, k;cout<<"Please enter the number of vertexes"<<endl;G->vertexnumber = i;cout<<"Please enter the data of each vertex in term"<<endl;for(j=0; j<i; j++) {cin>>k;k = G->vertextlist[j].data;G->vertextlist[j].firstadjin = NULL;G->vertextlist[j].firstadjout = NULL;}}void EdgeListCreate() {int i, j, s, e, w;cout<<"Please enter the number of edges"<<endl;cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w;EdgeListNode* edge;edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));edge->headvex = s;edge->tailvex = e;edge->taillink = G->vertextlist[s].firstadjout;G->vertextlist[s].firstadjout = edge;edge->headlink = G->vertextlist[e].firstadjin;G->vertextlist[e].firstadjin = edge;}}void CreateGraph() {VertexListInit();EdgeListCreate();}};

(3)实际示例

2.4 邻接多重表(针对无向图邻接链表的优化)

(1)总体思想
对于无向图而言,其每条边在邻接链表中都需要两个结点来表示,而邻接多重表正是对其进行优化,让同一条边只用一个结点表示即可。邻接多重表仿照了十字链表的思想,对邻接链表的边表结点进行了改进。

(2)具体实现
A. 数据结构
a. 顶点表中结点的结构:

typedef struct VertexListNode{int data;EdgeListNode* firstedge;
};

其中,firstedge指向该顶点的边表的第一个结点。

b. 边表中结点的结构:

typedef struct EdgeListNode{int ivex;EdgeListNode* ilink;int jvex;EdgeListNode* jlink;int weight;
};

其中,ivex和jvex是一条边的两个顶点在顶点表中的下标;ilink指向了表示图中另一条以ivex为其中一个顶点的边的边表结点,因为ivex的边表里每个结点表示的边都以ivex作为其中一个顶点,所以可以让ilink指向G->vertextlist[ivex].firstedge;jlink指向了表示图中另一条以jvex为其中一个顶点的边的边表结点,因为jvex的边表里每个结点表示的边都以jvex作为其中一个顶点,所以可以让jlink指向G->vertextlist[jvex].firstedge;weight表示这条边的权值。

c. 用邻接多重表表示的图结构:

typedef struct GraphMultiAdjList{int vertexnumber;int edgenumber;VertexListNode vertextlist[Maximum];
};

B. 图的创建
a. 初始化顶点表

 void VertexListInit() {int i, j, k;cout<<"Please enter the number of vertexes"<<endl;G->vertexnumber = i;cout<<"Please enter the data of each vertex in term"<<endl;for(j=0; j<i; j++) {cin>>k;k = G->vertextlist[j].data;G->vertextlist[j].firstedge = NULL;}}

b. 初始化边表

    void EdgeListCreate() {int i, j, k, s, e, w;cout<<"Please enter the number of edges"<<endl;cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w;EdgeListNode* edge;edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));edge->ivex = s;edge->jvex = e;edge->weight = w;/*G->vertextlist[s]里的结点表示的边都以s为其中一个顶点*/edge->ilink = G->vertextlist[s].firstedge;/*当前这条边也是以s为其中一个顶点的,因此可以让G->vertextlist[s].firstedge指向它*/G->vertextlist[s].firstedge = edge;/*G->vertextlist[e]里的结点表示的边都以e为其中一个顶点*/edge->jlink = G->vertextlist[e].firstedge;/*当前这条边也是以e为其中一个顶点的,因此可以让G->vertextlist[e].firstedge指向它*/G->vertextlist[e].firstedge = edge;}}

c. 综合起来,图的创建:

void CreateGraph() {VertexListInit();EdgeListCreate();}

C. 把上述内容封装起来,创建一个多重邻接表表示图的类:

#define Maximum 1000typedef struct EdgeListNode{int ivex;EdgeListNode* ilink;int jvex;EdgeListNode* jlink;int weight;
};typedef struct VertexListNode{int data;EdgeListNode* firstedge;
};typedef struct GraphMultiAdjList{int vertexnumber;int edgenumber;VertexListNode vertextlist[Maximum];
};class DirectGraph {
public:GraphMultiAdjList* G;DirectGraph() {G = (GraphMultiAdjList*)malloc(sizeof(GraphMultiAdjList));}void VertexListInit() {int i, j, k;cout<<"Please enter the number of vertexes"<<endl;G->vertexnumber = i;cout<<"Please enter the data of each vertex in term"<<endl;for(j=0; j<i; j++) {cin>>k;k = G->vertextlist[j].data;G->vertextlist[j].firstedge = NULL;}}void EdgeListCreate() {int i, j, k, s, e, w;cout<<"Please enter the number of edges"<<endl;cin>>i;G->edgenumber = i;cout<<"Please enter the information of each edge in term"<<endl;for(j=0; j<i; j++) {cin>>s>>e>>w;if(s > e) {k = s;s = e;e = k;}EdgeListNode* edge;edge = (EdgeListNode*)malloc(sizeof(EdgeListNode));edge->ivex = s;edge->jvex = e;edge->weight = w;edge->ilink = G->vertextlist[s].firstedge;G->vertextlist[s].firstedge = edge;edge->jlink = G->vertextlist[e].firstedge;G->vertextlist[e].firstedge = edge;}}void CreateGraph() {VertexListInit();EdgeListCreate();}};

2.5 边集数组

(1)基本思想
边集数组是由两个一维数组组成的:一个用于存储顶点的信息(顶点数组);一个用于存储边信息(边数组)。在边集数组中要查找一个顶点的度需要遍历整个边数组,效率并不高,因此它并不适合对顶点进行的相关操作,而更适合于对边依次进行处理的操作。

(2)数据结构
a. 顶点数组:

int vertexlist[Maximum]; //存放每个顶点的权值

b. 边数组里每一项的结构:

typedef struct EdgeArrayNode{int startvertex; //起点下标int endvertex; //终点下标int weight; //边的权值
};

c. 用边集数组表示的图的结构:

typedef struct GraphEdgeArray {int vertexnumber; //顶点数int edgenumber; //边数int vertexlist[Maximum];EdgeArrayNode edgearray[Maximum*Maximum];
};

(3)实际例子

图——基本的图算法(一)图的存储结构相关推荐

  1. 基于图数据库、图算法、图神经网络的 ID Resolution/ID Mapping 大数据分析方法与代码示例

    本文首发于 NebulaGraph 公众号 "本文是一个基于 NebulaGraph 上的图数据库.图算法.图神经网络的 ID Resolution/ID Mapping 方法综述,除了基本 ...

  2. 大话数据结构 -07-1 图的定义、抽象数据类型与存储结构

    1. 定义 在图结构中,结点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关. 2. 与线性表.树结构的区别 3. 相关定义 (1)无向.有向 与图边或者弧相关的数字叫做权(Weight), ...

  3. 数据结构-图(图的定义、分类、基本术语和存储结构)

    图 图(Graph)是由莱昂哈德·欧拉1在1736年首先引进的一类很重要的非线性结构,可称为图形结构或网状结构.图的应用领域非常广泛,例如:电路分析.工程规划.化合物分类.统计力学.自动化.语言学等. ...

  4. 5.4广义表的定义5.5广义表的存储结构

    广义表是线性表的推广. 广义表一般记作LS=(α1,α2,...,αn) n是它的长度αi可以是单个元素也可以说广义表,分别称为广义表LS的原子和子表. 当广义表LS非空时,称第一个元素α1为LS的表 ...

  5. 存储结构和磁盘划分(基于RedHat7)

    转载来自:http://www.linuxprobe.com/chapter-06.html(良心之作) 章节简述: Linux系统中颇具特色的文件存储结构常常搞的新手头晕,本章节将从Linux系统中 ...

  6. 2.1 linux 存储结构和硬盘划分

    2.1 一切从"/"开始 Linux系统中的目录.字符设备.块设备.套接字.打印机等等都被抽象成了文件,即刘遄老师所一直强调的--Linux系统中一切都是文件.既然平时跟咱们打交道 ...

  7. 第五天学习--存储结构与磁盘划分

    章节简述: Linux系统中颇具特色的文件存储结构常常搞得新手头晕脑胀,本章将从Linux系统中的文件存储结构开始,讲述文件系统层次化标准(FHS,Filesystem Hierarchy Stand ...

  8. 6.存储结构与磁盘划分

    第6章 存储结构与磁盘划分 章节简述: Linux系统中颇具特色的文件存储结构常常搞得新手头晕脑胀,本章将从Linux系统中的文件存储结构开始,讲述文件系统层次化标准(FHS,Filesystem H ...

  9. linux 存储结构与磁盘划分详解

    Linux系统中颇具特色的文件存储结构常常搞得新手头晕脑胀,本章将从Linux系统中的文件存储结构开始,讲述文件系统层次化标准(FHS,Filesystem Hierarchy Standard).u ...

  10. Linux就该这么学---第九天(存储结构与使用命令管理硬盘)

    文章目录 第六章-存储结构与管理磁盘 6.1 一切从"/"开始 6.2 物理设备的命名规则 6.3 文件系统与数据资料 inode与block 虚拟文件系统(Virutal Fil ...

最新文章

  1. 如何给6个整数的一维数组某个元素赋值_数组指针详解
  2. 改善Hibernate应用程序性能的7种方法
  3. 95-140-130-源码-transform-算子coGroup
  4. java 中文乱码过滤器_JAVA中文乱码过滤器(用java过滤器解决中文乱码)V0422 整理版...
  5. 软件著作权申请流程(自助申请免费登记)
  6. Silverlight 4 全屏
  7. pc端和移动端的区别
  8. MT7628学习笔记(13)——ipk软件包编写与应用
  9. 有实用简单的PS小技巧吗?下面几个小技巧你知道几个呢?
  10. 华为鸿蒙跑了个“hello world”!跑通后,我特么开始怀疑人生....
  11. C#使用ADO.NET访问数据库
  12. 宏碁E1-471G笔记本固态启动盘问题
  13. python moviepy 从视频中提取音频
  14. jdk API下载(英文的)
  15. 不同类型时钟CLK信号波形的产生、与时钟频率的关系
  16. HTML5不支持createtouch,新手写createjs时容易遇到的坑(持续更新)
  17. 模制适配器-市场现状及未来发展趋势
  18. 晨控CK-GW208-EC与欧姆龙PLC工业EtherCAT协议通讯指南
  19. MySQL01-Pycharm连接MySQL出现时差问题
  20. 鸿蒙系统有hms推送机制,华为推送HMS服务,依靠鸿蒙OS,或将改变手机行业格局...

热门文章

  1. 1.6 笔记本开机卡在logo页面(一直在加载转动,)关机重启几次也还是不行,自动修复也是失败
  2. [激光原理与应用-66]:激光器-器件 - 二极管
  3. 【排序算法】选择排序(C语言)
  4. 如何编写列名中带有空格的SQL查询
  5. 1.22链界观区块链资讯
  6. 使用栈计算前缀表达式
  7. ubuntu截屏快捷键
  8. 从游戏中得到动态内存数据
  9. 三星屏幕那么好,为什么华为mate 30 系列不全用?这两点原因是关键
  10. 远程过程调用(Remote Procedure Call)