mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 14:18:20 +08:00 
			
		
		
		
	add c code for graph operation (#601)
* Create chapter_graph * Delete chapter_graph * add C code for graph * add C code for graph * Create graph_adjacency_list.c add C code for graph * Update CMakeLists.txt * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update format and output * Update graph_adjacency_list.c * Update CMakeLists.txt for c code of graph * Update format of c code * Update format of c code * Update format of c code * Update verticesList Change the data structure of the storage list from a linked list to a linear table * Update graph_adjacency_list.c * Update graph_adjacency_matrix.c * Create graph_adjacency_list_test.c * Create graph_bfs * Update CMakeLists.txt * Update graph_adjacency_list.c * mv graph_bfs to graph_bfs.c * Update graph_bfs.c * Delete graph_bfs * Update graph_adjacency_list.c * update c code for graph operation. * Update CMakeLists.txt * Update graph_dfs.c * Update graph_dfs.c * Update CMakeLists.txt * Update graph_dfs.c * Update note of graph_dfs.c * Update graph_bfs.c * Update graph_dfs.c * Update graph_bfs.c * Update output "初始化后,图为:" of graph_dfs.c * Update graph_dfs.c * Update graph_bfs.c * Update graph_dfs.c * Update name of arrayVertex * Update name of arrayVertex * Update note of graph_dfs.c * Update note of graph_bfs.c * Update graph_dfs.c * Update graph_bfs.c * Update graph_adjacency_matrix.c * Update graph_adjacency_list_test.c * Update graph_adjacency_list.c * Update graph_dfs.c * Update graph_bfs.c * Update comment * Update comment * Update graph_adjacency_list.c * Update graph_adjacency_matrix.c * update comment * update comment * update comment for graph operation * update comment of graph operation * update comment * update comment --------- Co-authored-by: Yudong Jin <krahets@163.com> Co-authored-by: libr <libr@info2soft.com>
This commit is contained in:
		@ -1,4 +1,4 @@
 | 
				
			|||||||
add_executable(graph_adjacency_matrix graph_adjacency_matrix.c)
 | 
					add_executable(graph_adjacency_matrix graph_adjacency_matrix.c)
 | 
				
			||||||
add_executable(graph_adjacency_list graph_adjacency_list.c)
 | 
					 | 
				
			||||||
add_executable(graph_adjacency_list_test graph_adjacency_list_test.c)
 | 
					add_executable(graph_adjacency_list_test graph_adjacency_list_test.c)
 | 
				
			||||||
add_executable(graph_bfs graph_bfs.c)
 | 
					add_executable(graph_bfs graph_bfs.c)
 | 
				
			||||||
 | 
					add_executable(graph_dfs graph_dfs.c)
 | 
				
			||||||
 | 
				
			|||||||
@ -41,11 +41,11 @@ struct Vertex {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 顶点节点构造函数 */
 | 
					/* 顶点节点构造函数 */
 | 
				
			||||||
Vertex *newVertex(int val) {
 | 
					Vertex *newVertex(int val) {
 | 
				
			||||||
    Vertex *v = (Vertex *)malloc(sizeof(Vertex));
 | 
					    Vertex *vet = (Vertex *)malloc(sizeof(Vertex));
 | 
				
			||||||
    // 为新节点赋值并建立该节点的链表
 | 
					    // 为新节点赋值并建立该节点的链表
 | 
				
			||||||
    v->val = val;
 | 
					    vet->val = val;
 | 
				
			||||||
    v->linked = newLinklist(v);
 | 
					    vet->linked = newLinklist(vet);
 | 
				
			||||||
    return v;
 | 
					    return vet;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 顶点内存释放函数 */
 | 
					/* 顶点内存释放函数 */
 | 
				
			||||||
@ -103,25 +103,6 @@ void removeLink(linkList *l, Vertex *val) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 根据索引查找链表中节点 */
 | 
					 | 
				
			||||||
Node *findByindex(linkList *l, unsigned int index) {
 | 
					 | 
				
			||||||
    unsigned int i = 0;
 | 
					 | 
				
			||||||
    Node *temp = l->head->next;
 | 
					 | 
				
			||||||
    while (temp != 0) {
 | 
					 | 
				
			||||||
        if (i == index) {
 | 
					 | 
				
			||||||
            return temp;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        temp = temp->next;
 | 
					 | 
				
			||||||
        i++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (temp->next == 0) {
 | 
					 | 
				
			||||||
        printf("vertex not found!\n");
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 根据顶点地址删除顶点 */
 | 
					/* 根据顶点地址删除顶点 */
 | 
				
			||||||
void removeNode(linkList *l, Vertex *val) {
 | 
					void removeNode(linkList *l, Vertex *val) {
 | 
				
			||||||
    Node *temp = l->head->next;
 | 
					    Node *temp = l->head->next;
 | 
				
			||||||
@ -172,12 +153,9 @@ linkList *newLinklist(Vertex *val) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 基于邻接链表实现的无向图类结构 */
 | 
					/* 基于邻接链表实现的无向图类结构 */
 | 
				
			||||||
struct graphAdjList {
 | 
					struct graphAdjList {
 | 
				
			||||||
    // 顶点列表
 | 
					    Vertex **verticesList; // 邻接表
 | 
				
			||||||
    Vertex **verticesList;
 | 
					    unsigned int size;     // 顶点数量
 | 
				
			||||||
    // 顶点数量
 | 
					    unsigned int capacity; // 顶点容量
 | 
				
			||||||
    unsigned int size;
 | 
					 | 
				
			||||||
    // 当前容量
 | 
					 | 
				
			||||||
    unsigned int capacity;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct graphAdjList graphAdjList;
 | 
					typedef struct graphAdjList graphAdjList;
 | 
				
			||||||
@ -189,13 +167,13 @@ void addEdge(graphAdjList *t, int i, int j) {
 | 
				
			|||||||
        printf("Out of range in %s:%d\n", __FILE__, __LINE__);
 | 
					        printf("Out of range in %s:%d\n", __FILE__, __LINE__);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // 查找待连接的节点
 | 
					    // 查找欲添加边的顶点 vet1 - vet2
 | 
				
			||||||
    Vertex *v1 = t->verticesList[i];
 | 
					    Vertex *vet1 = t->verticesList[i];
 | 
				
			||||||
    Vertex *v2 = t->verticesList[j];
 | 
					    Vertex *vet2 = t->verticesList[j];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 连接节点
 | 
					    // 连接顶点 vet1 - vet2
 | 
				
			||||||
    pushBack(v1->linked, v2);
 | 
					    pushBack(vet1->linked, vet2);
 | 
				
			||||||
    pushBack(v2->linked, v1);
 | 
					    pushBack(vet2->linked, vet1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 删除边 */
 | 
					/* 删除边 */
 | 
				
			||||||
@ -206,13 +184,13 @@ void removeEdge(graphAdjList *t, int i, int j) {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 查找待删除边的相关节点
 | 
					    // 查找欲删除边的顶点 vet1 - vet2
 | 
				
			||||||
    Vertex *v1 = t->verticesList[i];
 | 
					    Vertex *vet1 = t->verticesList[i];
 | 
				
			||||||
    Vertex *v2 = t->verticesList[j];
 | 
					    Vertex *vet2 = t->verticesList[j];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 移除待删除边
 | 
					    // 移除待删除边 vet1 - vet2
 | 
				
			||||||
    removeLink(v1->linked, v2);
 | 
					    removeLink(vet1->linked, vet2);
 | 
				
			||||||
    removeLink(v2->linked, v1);
 | 
					    removeLink(vet2->linked, vet1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 添加顶点 */
 | 
					/* 添加顶点 */
 | 
				
			||||||
@ -221,16 +199,15 @@ void addVertex(graphAdjList *t, int val) {
 | 
				
			|||||||
    if (t->size >= t->capacity) {
 | 
					    if (t->size >= t->capacity) {
 | 
				
			||||||
        Vertex **tempList = (Vertex **)malloc(sizeof(Vertex *) * 2 * t->capacity);
 | 
					        Vertex **tempList = (Vertex **)malloc(sizeof(Vertex *) * 2 * t->capacity);
 | 
				
			||||||
        memcpy(tempList, t->verticesList, sizeof(Vertex *) * t->size);
 | 
					        memcpy(tempList, t->verticesList, sizeof(Vertex *) * t->size);
 | 
				
			||||||
        free(t->verticesList);
 | 
					        free(t->verticesList);         // 释放原邻接表内存
 | 
				
			||||||
        // 指向新顶点表
 | 
					        t->verticesList = tempList;    // 指向新邻接表
 | 
				
			||||||
        t->verticesList = tempList;    
 | 
					        t->capacity = t->capacity * 2; // 容量扩大至2倍
 | 
				
			||||||
        t->capacity = t->capacity * 2;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // 申请新顶点内存并将新顶点地址存入顶点列表
 | 
					    // 申请新顶点内存并将新顶点地址存入顶点列表
 | 
				
			||||||
    Vertex *newV = newVertex(val);
 | 
					    Vertex *newV = newVertex(val);    // 建立新顶点
 | 
				
			||||||
    newV->pos = t->size;
 | 
					    newV->pos = t->size;              // 为新顶点标记下标
 | 
				
			||||||
    newV->linked = newLinklist(newV);
 | 
					    newV->linked = newLinklist(newV); // 为新顶点建立链表
 | 
				
			||||||
    t->verticesList[t->size] = newV;
 | 
					    t->verticesList[t->size] = newV;  // 将新顶点加入邻接表
 | 
				
			||||||
    t->size++;
 | 
					    t->size++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -242,31 +219,30 @@ void removeVertex(graphAdjList *t, unsigned int index) {
 | 
				
			|||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 查找待删节点
 | 
					    Vertex *vet = t->verticesList[index]; // 查找待删节点
 | 
				
			||||||
    Vertex *v = t->verticesList[index];
 | 
					    if (vet == 0) {                       // 若不存在该节点,则返回
 | 
				
			||||||
    // 若不存在该节点,则返回
 | 
					 | 
				
			||||||
    if (v == 0) {
 | 
					 | 
				
			||||||
        printf("index is:%d\n", index);
 | 
					        printf("index is:%d\n", index);
 | 
				
			||||||
        printf("Out of range in %s:%d\n", __FILE__, __LINE__);
 | 
					        printf("Out of range in %s:%d\n", __FILE__, __LINE__);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 遍历待删除节点链表,将所有与待删除结点有关的边删除
 | 
					    // 遍历待删除顶点的链表,将所有与待删除结点有关的边删除
 | 
				
			||||||
    Node *temp = v->linked->head->next;
 | 
					    Node *temp = vet->linked->head->next;
 | 
				
			||||||
    while (temp != 0) {
 | 
					    while (temp != 0) {
 | 
				
			||||||
        removeLink(temp->val->linked, v);
 | 
					        removeLink(temp->val->linked, vet); // 删除与该顶点有关的边
 | 
				
			||||||
        temp = temp->next;                
 | 
					        temp = temp->next;                
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 定点列表前移
 | 
					    // 将顶点前移
 | 
				
			||||||
    for (int i = index; i < t->size - 1; i++) {
 | 
					    for (int i = index; i < t->size - 1; i++) {
 | 
				
			||||||
        t->verticesList[i] = t->verticesList[i + 1];
 | 
					        t->verticesList[i] = t->verticesList[i + 1]; // 顶点前移
 | 
				
			||||||
 | 
					        t->verticesList[i]->pos--;                   // 所有前移的顶点索引值减1
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    t->verticesList[t->size - 1] = 0;
 | 
					    t->verticesList[t->size - 1] = 0; // 将被删除顶点的位置置 0
 | 
				
			||||||
    t->size--;
 | 
					    t->size--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //释放被删除顶点的内存
 | 
					    //释放被删除顶点的内存
 | 
				
			||||||
    freeVertex(v);
 | 
					    freeVertex(vet);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 打印顶点与邻接矩阵 */
 | 
					/* 打印顶点与邻接矩阵 */
 | 
				
			||||||
@ -288,14 +264,14 @@ void printGraph(graphAdjList *t) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 构造函数 */
 | 
					/* 构造函数 */
 | 
				
			||||||
graphAdjList *newGraphic(unsigned int verticesNumber) {
 | 
					graphAdjList *newGraphAdjList(unsigned int verticesCapacity) {
 | 
				
			||||||
    // 申请内存
 | 
					    // 申请内存
 | 
				
			||||||
    graphAdjList *newGraph = (graphAdjList *)malloc(sizeof(graphAdjList));
 | 
					    graphAdjList *newGraph = (graphAdjList *)malloc(sizeof(graphAdjList));
 | 
				
			||||||
    // 建立顶点表并分配内存
 | 
					    // 建立顶点表并分配内存
 | 
				
			||||||
    newGraph->verticesList = (Vertex **)malloc(sizeof(Vertex *) * verticesNumber);
 | 
					    newGraph->verticesList = (Vertex **)malloc(sizeof(Vertex *) * verticesCapacity); // 为顶点列表分配内存
 | 
				
			||||||
    memset(newGraph->verticesList, 0, sizeof(Vertex *) * verticesNumber);
 | 
					    memset(newGraph->verticesList, 0, sizeof(Vertex *) * verticesCapacity);          // 顶点列表置 0
 | 
				
			||||||
    // 初始化大小和容量
 | 
					    newGraph->size = 0;                                                              // 初始化顶点数量
 | 
				
			||||||
    newGraph->size = 0;
 | 
					    newGraph->capacity = verticesCapacity;                                           // 初始化顶点容量
 | 
				
			||||||
    newGraph->capacity = verticesNumber;
 | 
					    // 返回图指针
 | 
				
			||||||
    return newGraph;                
 | 
					    return newGraph;                
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,7 @@
 | 
				
			|||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 初始化无向图 */
 | 
					    /* 初始化无向图 */
 | 
				
			||||||
    graphAdjList *graph = newGraphic(5);
 | 
					    graphAdjList *graph = newGraphAdjList(5);
 | 
				
			||||||
    // 初始化顶点
 | 
					    // 初始化顶点
 | 
				
			||||||
    addVertex(graph, 1);
 | 
					    addVertex(graph, 1);
 | 
				
			||||||
    addVertex(graph, 3);
 | 
					    addVertex(graph, 3);
 | 
				
			||||||
 | 
				
			|||||||
@ -8,32 +8,38 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 基于邻接矩阵实现的无向图类结构 */
 | 
					/* 基于邻接矩阵实现的无向图类结构 */
 | 
				
			||||||
struct graphAdjMat {
 | 
					struct graphAdjMat {
 | 
				
			||||||
    int *vertices;
 | 
					    int *vertices;         // 顶点列表
 | 
				
			||||||
    unsigned int **adjMat;
 | 
					    unsigned int **adjMat; // 邻接矩阵,元素代表“边”,索引代表“顶点索引”
 | 
				
			||||||
    unsigned int size;
 | 
					    unsigned int size;     // 顶点数量
 | 
				
			||||||
    unsigned int capacity;
 | 
					    unsigned int capacity; // 图容量
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct graphAdjMat graphAdjMat;
 | 
					typedef struct graphAdjMat graphAdjMat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 添加边 */
 | 
					/* 添加边 */
 | 
				
			||||||
 | 
					// 参数 i, j 对应 vertices 元素索引
 | 
				
			||||||
void addEdge(graphAdjMat *t, int i, int j) {
 | 
					void addEdge(graphAdjMat *t, int i, int j) {
 | 
				
			||||||
    // 越界检查
 | 
					    // 越界检查
 | 
				
			||||||
    if (i < 0 || j < 0 || i >= t->size || j >= t->size || i == j) {
 | 
					    if (i < 0 || j < 0 || i >= t->size || j >= t->size || i == j) {
 | 
				
			||||||
        printf("Out of range in %s:%d\n", __FILE__, __LINE__);
 | 
					        printf("Out of range in %s:%d\n", __FILE__, __LINE__);
 | 
				
			||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    // 添加边
 | 
				
			||||||
 | 
					    // 参数 i, j 对应 vertices 元素索引
 | 
				
			||||||
    t->adjMat[i][j] = 1;
 | 
					    t->adjMat[i][j] = 1;
 | 
				
			||||||
    t->adjMat[j][i] = 1;
 | 
					    t->adjMat[j][i] = 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 删除边 */
 | 
					/* 删除边 */
 | 
				
			||||||
 | 
					// 参数 i, j 对应 vertices 元素索引
 | 
				
			||||||
void removeEdge(graphAdjMat *t, int i, int j) {
 | 
					void removeEdge(graphAdjMat *t, int i, int j) {
 | 
				
			||||||
    // 越界检查
 | 
					    // 越界检查
 | 
				
			||||||
    if (i < 0 || j < 0 || i >= t->size || j >= t->size || i == j) {
 | 
					    if (i < 0 || j < 0 || i >= t->size || j >= t->size || i == j) {
 | 
				
			||||||
        printf("Out of range in %s:%d\n", __FILE__, __LINE__);
 | 
					        printf("Out of range in %s:%d\n", __FILE__, __LINE__);
 | 
				
			||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    // 删除边
 | 
				
			||||||
 | 
					    // 参数 i, j 对应 vertices 元素索引
 | 
				
			||||||
    t->adjMat[i][j] = 0;
 | 
					    t->adjMat[i][j] = 0;
 | 
				
			||||||
    t->adjMat[j][i] = 0;
 | 
					    t->adjMat[j][i] = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -42,13 +48,13 @@ void removeEdge(graphAdjMat *t, int i, int j) {
 | 
				
			|||||||
void addVertex(graphAdjMat *t, int val) {
 | 
					void addVertex(graphAdjMat *t, int val) {
 | 
				
			||||||
    // 如果实际使用不大于预设空间,则直接初始化新空间
 | 
					    // 如果实际使用不大于预设空间,则直接初始化新空间
 | 
				
			||||||
    if (t->size < t->capacity) {
 | 
					    if (t->size < t->capacity) {
 | 
				
			||||||
        t->vertices[t->size] = val;
 | 
					        t->vertices[t->size] = val; // 初始化新顶点值
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // 邻接矩新列阵置0
 | 
					 | 
				
			||||||
        for (int i = 0; i < t->size; i++) {
 | 
					        for (int i = 0; i < t->size; i++) {
 | 
				
			||||||
            t->adjMat[i][t->size] = 0;
 | 
					            t->adjMat[i][t->size] = 0; // 邻接矩新列阵置0
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        memset(t->adjMat[t->size], 0, sizeof(unsigned int) * (t->size + 1));
 | 
					        memset(t->adjMat[t->size], 0, sizeof(unsigned int) * (t->size + 1)); // 将新增行置 0
 | 
				
			||||||
        t->size++;
 | 
					        t->size++;
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -70,23 +76,21 @@ void addVertex(graphAdjMat *t, int val) {
 | 
				
			|||||||
        tempMat[k] = tempMatLine + k * (t->size * 2);
 | 
					        tempMat[k] = tempMatLine + k * (t->size * 2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 原数据复制到新数组
 | 
					 | 
				
			||||||
    for (int i = 0; i < t->size; i++) {
 | 
					    for (int i = 0; i < t->size; i++) {
 | 
				
			||||||
        memcpy(tempMat[i], t->adjMat[i], sizeof(unsigned int) * t->size);
 | 
					        memcpy(tempMat[i], t->adjMat[i], sizeof(unsigned int) * t->size); // 原数据复制到新数组
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 新列置0
 | 
					 | 
				
			||||||
    for (int i = 0; i < t->size; i++) {
 | 
					    for (int i = 0; i < t->size; i++) {
 | 
				
			||||||
        tempMat[i][t->size] = 0;
 | 
					        tempMat[i][t->size] = 0; // 将新增列置 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    memset(tempMat[t->size], 0, sizeof(unsigned int) * (t->size + 1));
 | 
					    memset(tempMat[t->size], 0, sizeof(unsigned int) * (t->size + 1)); // 将新增行置 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 释放原数组
 | 
					    // 释放原数组
 | 
				
			||||||
    free(t->adjMat[0]);
 | 
					    free(t->adjMat[0]);
 | 
				
			||||||
    free(t->adjMat);
 | 
					    free(t->adjMat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 扩容后,指向新地址
 | 
					    // 扩容后,指向新地址
 | 
				
			||||||
    t->adjMat = tempMat;
 | 
					    t->adjMat = tempMat;  // 指向新的邻接矩阵地址
 | 
				
			||||||
    t->capacity = t->size * 2;
 | 
					    t->capacity = t->size * 2;
 | 
				
			||||||
    t->size++;
 | 
					    t->size++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -98,28 +102,21 @@ void removeVertex(graphAdjMat *t, unsigned int index) {
 | 
				
			|||||||
        printf("Out of range in %s:%d\n", __FILE__, __LINE__);
 | 
					        printf("Out of range in %s:%d\n", __FILE__, __LINE__);
 | 
				
			||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 清除删除的顶点,并将其后所有顶点前移
 | 
					 | 
				
			||||||
    for (int i = index; i < t->size - 1; i++) {
 | 
					    for (int i = index; i < t->size - 1; i++) {
 | 
				
			||||||
        t->vertices[i] = t->vertices[i + 1];
 | 
					        t->vertices[i] = t->vertices[i + 1]; // 清除删除的顶点,并将其后所有顶点前移
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    t->vertices[t->size - 1] = 0; // 将被前移的最后一个顶点置 0
 | 
				
			||||||
    // 将被前移的最后一个顶点置0
 | 
					 | 
				
			||||||
    t->vertices[t->size - 1] = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 清除邻接矩阵中删除的列
 | 
					    // 清除邻接矩阵中删除的列
 | 
				
			||||||
    for (int i = 0; i < t->size - 1; i++) {
 | 
					    for (int i = 0; i < t->size - 1; i++) {
 | 
				
			||||||
        if (i < index) {
 | 
					        if (i < index) {
 | 
				
			||||||
            // 被删除列后的所有列前移
 | 
					 | 
				
			||||||
            for (int j = index; j < t->size - 1; j++) {
 | 
					            for (int j = index; j < t->size - 1; j++) {
 | 
				
			||||||
                t->adjMat[i][j] = t->adjMat[i][j + 1];
 | 
					                t->adjMat[i][j] = t->adjMat[i][j + 1]; // 被删除列后的所有列前移
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else { 
 | 
					        } else { 
 | 
				
			||||||
            // 被删除行的下方所有行上移
 | 
					            memcpy(t->adjMat[i], t->adjMat[i + 1], sizeof(unsigned int) * t->size); // 被删除行的下方所有行上移
 | 
				
			||||||
            memcpy(t->adjMat[i], t->adjMat[i + 1], sizeof(unsigned int) * t->size);
 | 
					 | 
				
			||||||
            // 被删除列后的所有列前移
 | 
					 | 
				
			||||||
            for (int j = index; j < t->size; j++) {
 | 
					            for (int j = index; j < t->size; j++) {
 | 
				
			||||||
                t->adjMat[i][j] = t->adjMat[i][j + 1];
 | 
					                t->adjMat[i][j] = t->adjMat[i][j + 1]; // 被删除列后的所有列前移
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -157,45 +154,41 @@ void printGraph(graphAdjMat *t) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 构造函数 */
 | 
					/* 构造函数 */
 | 
				
			||||||
graphAdjMat *newGraphic(unsigned int numberVertices, int *vertices, unsigned int **adjMat) {
 | 
					graphAdjMat *newGraphAjdMat(unsigned int numberVertices, int *vertices, unsigned int **adjMat) {
 | 
				
			||||||
    // 函数指针
 | 
					 | 
				
			||||||
    graphAdjMat *newGraph = (graphAdjMat *)malloc(sizeof(graphAdjMat));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 申请内存
 | 
					    // 申请内存
 | 
				
			||||||
    newGraph->vertices = (int *)malloc(sizeof(int) * numberVertices * 2);
 | 
					    graphAdjMat *newGraph = (graphAdjMat *)malloc(sizeof(graphAdjMat));                                          // 为图分配内存
 | 
				
			||||||
    newGraph->adjMat = (unsigned int **)malloc(sizeof(unsigned int *) * numberVertices * 2);
 | 
					    newGraph->vertices = (int *)malloc(sizeof(int) * numberVertices * 2);                                        // 为顶点列表分配内存
 | 
				
			||||||
    unsigned int *temp = (unsigned int *)malloc(sizeof(unsigned int) * numberVertices * 2 * numberVertices * 2);
 | 
					    newGraph->adjMat = (unsigned int **)malloc(sizeof(unsigned int *) * numberVertices * 2);                     // 为邻接矩阵分配二维内存
 | 
				
			||||||
    newGraph->size = numberVertices;
 | 
					    unsigned int *temp = (unsigned int *)malloc(sizeof(unsigned int) * numberVertices * 2 * numberVertices * 2); // 为邻接矩阵分配一维内存
 | 
				
			||||||
    newGraph->capacity = numberVertices * 2;
 | 
					    newGraph->size = numberVertices;                                                                             // 初始化顶点数量
 | 
				
			||||||
 | 
					    newGraph->capacity = numberVertices * 2;                                                                     // 初始化图容量
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 配置二维数组
 | 
					    // 配置二维数组
 | 
				
			||||||
    for (int i = 0; i < numberVertices * 2; i++) {
 | 
					    for (int i = 0; i < numberVertices * 2; i++) {
 | 
				
			||||||
        newGraph->adjMat[i] = temp + i * numberVertices * 2;
 | 
					        newGraph->adjMat[i] = temp + i * numberVertices * 2; // 将二维指针指向一维数组
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 赋值
 | 
					    // 赋值
 | 
				
			||||||
    memcpy(newGraph->vertices, vertices, sizeof(int) * numberVertices);
 | 
					    memcpy(newGraph->vertices, vertices, sizeof(int) * numberVertices);
 | 
				
			||||||
    for (int i = 0; i < numberVertices; i++) {
 | 
					    for (int i = 0; i < numberVertices; i++) {
 | 
				
			||||||
        memcpy(newGraph->adjMat[i], adjMat[i], sizeof(unsigned int) * numberVertices);
 | 
					        memcpy(newGraph->adjMat[i], adjMat[i], sizeof(unsigned int) * numberVertices); // 将传入的邻接矩阵赋值给结构体内邻接矩阵
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 返回结构体指针
 | 
				
			||||||
    return newGraph;
 | 
					    return newGraph;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Driver Code */
 | 
					/* Driver Code */
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* 初始化无向图 */
 | 
					    /* 初始化无向图 */
 | 
				
			||||||
    int vertices[5] = {1, 3, 2, 5, 4};
 | 
					    int vertices[5] = {1, 3, 2, 5, 4};
 | 
				
			||||||
    unsigned int **edge = (unsigned int **)malloc(sizeof(unsigned int *) * 5);
 | 
					    unsigned int **edge = (unsigned int **)malloc(sizeof(unsigned int *) * 5);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 用于构建二维数组的一维指针
 | 
					    // 用于构建二维数组的一维指针
 | 
				
			||||||
    unsigned int *temp = (unsigned int *)malloc(sizeof(unsigned int) * 25);
 | 
					    unsigned int *temp = (unsigned int *)malloc(sizeof(unsigned int) * 25);
 | 
				
			||||||
    memset(temp, 0, sizeof(unsigned int) * 25);
 | 
					    memset(temp, 0, sizeof(unsigned int) * 25);
 | 
				
			||||||
    for (int k = 0; k < 5; k++) {
 | 
					    for (int k = 0; k < 5; k++) {
 | 
				
			||||||
        edge[k] = temp + k * 5;
 | 
					        edge[k] = temp + k * 5;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 初始化边
 | 
					    // 初始化边
 | 
				
			||||||
    edge[0][1] = edge[1][0] = 1;
 | 
					    edge[0][1] = edge[1][0] = 1;
 | 
				
			||||||
    edge[0][3] = edge[3][0] = 1;
 | 
					    edge[0][3] = edge[3][0] = 1;
 | 
				
			||||||
@ -203,9 +196,8 @@ int main() {
 | 
				
			|||||||
    edge[2][3] = edge[3][2] = 1;
 | 
					    edge[2][3] = edge[3][2] = 1;
 | 
				
			||||||
    edge[2][4] = edge[4][2] = 1;
 | 
					    edge[2][4] = edge[4][2] = 1;
 | 
				
			||||||
    edge[3][4] = edge[4][3] = 1;
 | 
					    edge[3][4] = edge[4][3] = 1;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 建立无向图
 | 
					    // 建立无向图
 | 
				
			||||||
    graphAdjMat *graph = newGraphic(5, vertices, edge);
 | 
					    graphAdjMat *graph = newGraphAjdMat(5, vertices, edge);
 | 
				
			||||||
    free(edge);
 | 
					    free(edge);
 | 
				
			||||||
    free(temp);
 | 
					    free(temp);
 | 
				
			||||||
    printf("\n初始化后,图为:\n");
 | 
					    printf("\n初始化后,图为:\n");
 | 
				
			||||||
 | 
				
			|||||||
@ -30,11 +30,11 @@ void hashMark(hashTable *h, int index) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 查询顶点是否已被标记 */
 | 
					/* 查询顶点是否已被标记 */
 | 
				
			||||||
int hashQuery(hashTable *h, int index) {
 | 
					int hashQuery(hashTable *h, int index) {
 | 
				
			||||||
    // 若顶点已被标记,则返回 0
 | 
					    // 若顶点已被标记,则返回 1
 | 
				
			||||||
    if (h->array[index % h->size] == 1) {
 | 
					    if (h->array[index % h->size] == 1) {
 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -66,8 +66,8 @@ queue *newQueue(unsigned int size) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 入队 */
 | 
					/* 入队 */
 | 
				
			||||||
void queuePush(queue *q, Vertex *v) {
 | 
					void queuePush(queue *q, Vertex *vet) {
 | 
				
			||||||
    q->list[q->tail] = v;
 | 
					    q->list[q->tail] = vet;
 | 
				
			||||||
    q->tail++;
 | 
					    q->tail++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -88,46 +88,49 @@ void freeQueue(queue *q) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 广度优先遍历 */
 | 
					/* 广度优先遍历 */
 | 
				
			||||||
void graphBFS(graphAdjList *t) {
 | 
					// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
 | 
				
			||||||
    // 初始化队列与哈希表
 | 
					Vertex **graphBFS(graphAdjList *t, Vertex *startVet) {
 | 
				
			||||||
 | 
					    // 顶点遍历序列
 | 
				
			||||||
 | 
					    Vertex **res = (Vertex **)malloc(sizeof(Vertex *) * t->size);
 | 
				
			||||||
 | 
					    memset(res, 0, sizeof(Vertex *) * t->size);
 | 
				
			||||||
 | 
					    // 队列用于实现 BFS
 | 
				
			||||||
    queue *que = newQueue(t->size);
 | 
					    queue *que = newQueue(t->size);
 | 
				
			||||||
 | 
					    // 哈希表,用于记录已被访问过的顶点
 | 
				
			||||||
    hashTable *visited = newHash(t->size);
 | 
					    hashTable *visited = newHash(t->size);
 | 
				
			||||||
    // 将第一个元素入队
 | 
					    int resIndex = 0;
 | 
				
			||||||
    queuePush(que, t->verticesList[0]);
 | 
					    queuePush(que, startVet);         // 将第一个元素入队
 | 
				
			||||||
    hashMark(visited, t->verticesList[0]->pos);
 | 
					    hashMark(visited, startVet->pos); // 标记第一个入队的顶点
 | 
				
			||||||
 | 
					    // 以顶点 vet 为起点,循环直至访问完所有顶点
 | 
				
			||||||
    printf("\n[");
 | 
					 | 
				
			||||||
    while (que->head < que->tail) {
 | 
					    while (que->head < que->tail) {
 | 
				
			||||||
        // 遍历该顶点的边链表,将所有与该顶点有连接的,并且未被标记的顶点入队
 | 
					        // 遍历该顶点的边链表,将所有与该顶点有连接的,并且未被标记的顶点入队
 | 
				
			||||||
        Node *n = queueTop(que)->linked->head->next;
 | 
					        Node *n = queueTop(que)->linked->head->next;
 | 
				
			||||||
        while (n != 0) {
 | 
					        while (n != 0) {
 | 
				
			||||||
            // 查询哈希表,若该索引的顶点已入队,则跳过,否则入队并标记
 | 
					            // 查询哈希表,若该索引的顶点已入队,则跳过,否则入队并标记
 | 
				
			||||||
            if (hashQuery(visited, n->val->pos) != 0) {
 | 
					            if (hashQuery(visited, n->val->pos) == 1) {
 | 
				
			||||||
                queuePush(que, n->val);
 | 
					 | 
				
			||||||
                hashMark(visited, n->val->pos);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
                n = n->next;
 | 
					                n = n->next;
 | 
				
			||||||
 | 
					                continue; // 跳过已被访问过的顶点
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        // 打印队首元素
 | 
					            queuePush(que, n->val);         // 只入队未访问的顶点
 | 
				
			||||||
        if (que->head == que->tail - 1) {
 | 
					            hashMark(visited, n->val->pos); // 标记该顶点已被访问
 | 
				
			||||||
            printf("%d]\n", queueTop(que)->val);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            printf("%d, ", queueTop(que)->val);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // 队首元素出队
 | 
					        // 队首元素存入数组
 | 
				
			||||||
        queuePop(que);
 | 
					        res[resIndex] = queueTop(que); // 队首顶点加入顶点遍历序列
 | 
				
			||||||
 | 
					        resIndex++;
 | 
				
			||||||
 | 
					        queuePop(que); // 队首元素出队
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    printf("\n");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 释放队列与哈希表内存
 | 
					    // 释放内存
 | 
				
			||||||
    freeQueue(que);
 | 
					    freeQueue(que);
 | 
				
			||||||
    freeHash(visited);
 | 
					    freeHash(visited);
 | 
				
			||||||
 | 
					    resIndex = 0;
 | 
				
			||||||
 | 
					    // 返回顶点遍历序列
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* 初始化无向图 */
 | 
					    /* 初始化无向图 */
 | 
				
			||||||
    graphAdjList *graph = newGraphic(3);
 | 
					    graphAdjList *graph = newGraphAdjList(3);
 | 
				
			||||||
    // 初始化顶点
 | 
					    // 初始化顶点
 | 
				
			||||||
    for (int i = 0; i < 10; i++) {
 | 
					    for (int i = 0; i < 10; i++) {
 | 
				
			||||||
        addVertex(graph, i);
 | 
					        addVertex(graph, i);
 | 
				
			||||||
@ -145,13 +148,19 @@ int main() {
 | 
				
			|||||||
    addEdge(graph, 5, 8);
 | 
					    addEdge(graph, 5, 8);
 | 
				
			||||||
    addEdge(graph, 6, 7);
 | 
					    addEdge(graph, 6, 7);
 | 
				
			||||||
    addEdge(graph, 7, 8);
 | 
					    addEdge(graph, 7, 8);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    printf("\n初始化后,图为:\n");
 | 
					    printf("\n初始化后,图为:\n");
 | 
				
			||||||
    printGraph(graph);
 | 
					    printGraph(graph);
 | 
				
			||||||
 | 
					    printf("\n广度优先遍历(BFS)顶点序列为\n");
 | 
				
			||||||
 | 
					    Vertex **vets = graphBFS(graph, graph->verticesList[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("\n广度优先遍历(BFS)顶点序列为");
 | 
					    // 打印广度优先遍历数组
 | 
				
			||||||
    graphBFS(graph);
 | 
					    printf("[");
 | 
				
			||||||
 | 
					    printf("%d", vets[0]->val);
 | 
				
			||||||
 | 
					    for (int i = 1; i < graph->size && vets[i] != 0; i++) {
 | 
				
			||||||
 | 
					        printf(", %d", vets[i]->val);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf("]\n");
 | 
				
			||||||
 | 
					    free(vets);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										112
									
								
								codes/c/chapter_graph/graph_dfs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								codes/c/chapter_graph/graph_dfs.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,112 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * File: graph_dfs.c
 | 
				
			||||||
 | 
					 * Created Time: 2023-07-13
 | 
				
			||||||
 | 
					 * Author: NI-SW (947743645@qq.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "graph_adjacency_list.c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 哈希表 */
 | 
				
			||||||
 | 
					struct hashTable {
 | 
				
			||||||
 | 
					    unsigned int size;
 | 
				
			||||||
 | 
					    unsigned int *array;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct hashTable hashTable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 初始化哈希表 */
 | 
				
			||||||
 | 
					hashTable *newHash(unsigned int size) {
 | 
				
			||||||
 | 
					    hashTable *h = (hashTable *)malloc(sizeof(hashTable));
 | 
				
			||||||
 | 
					    h->array = (unsigned int *)malloc(sizeof(unsigned int) * size);
 | 
				
			||||||
 | 
					    memset(h->array, 0, sizeof(unsigned int) * size);
 | 
				
			||||||
 | 
					    h->size = size;
 | 
				
			||||||
 | 
					    return h;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 标记索引过的顶点 */
 | 
				
			||||||
 | 
					void hashMark(hashTable *h, int index) {
 | 
				
			||||||
 | 
					    h->array[index % h->size] = 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 查询顶点是否已被标记 */
 | 
				
			||||||
 | 
					int hashQuery(hashTable *h, int index) {
 | 
				
			||||||
 | 
					    // 若顶点已被标记,则返回 1
 | 
				
			||||||
 | 
					    if (h->array[index % h->size] == 1) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 释放哈希表内存 */
 | 
				
			||||||
 | 
					void freeHash(hashTable *h) {
 | 
				
			||||||
 | 
					    free(h->array);
 | 
				
			||||||
 | 
					    free(h);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 深度优先遍历 DFS 辅助函数 */
 | 
				
			||||||
 | 
					int resIndex = 0;
 | 
				
			||||||
 | 
					void dfs(graphAdjList *graph, hashTable *visited, Vertex *vet, Vertex **res) {
 | 
				
			||||||
 | 
					    if (hashQuery(visited, vet->pos) == 1) {
 | 
				
			||||||
 | 
					        return; // 跳过已被访问过的顶点
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    hashMark(visited, vet->pos); // 标记顶点并将顶点存入数组
 | 
				
			||||||
 | 
					    res[resIndex] = vet;         // 将顶点存入数组
 | 
				
			||||||
 | 
					    resIndex++;
 | 
				
			||||||
 | 
					    // 遍历该顶点链表
 | 
				
			||||||
 | 
					    Node *n = vet->linked->head->next;
 | 
				
			||||||
 | 
					    while (n != 0) {
 | 
				
			||||||
 | 
					        // 递归访问邻接顶点
 | 
				
			||||||
 | 
					        dfs(graph, visited, n->val, res);
 | 
				
			||||||
 | 
					        n = n->next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 深度优先遍历 DFS */
 | 
				
			||||||
 | 
					// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
 | 
				
			||||||
 | 
					Vertex **graphDFS(graphAdjList *graph, Vertex *startVet) {
 | 
				
			||||||
 | 
					    // 顶点遍历序列
 | 
				
			||||||
 | 
					    Vertex **res = (Vertex **)malloc(sizeof(Vertex *) * graph->size);
 | 
				
			||||||
 | 
					    memset(res, 0, sizeof(Vertex *) * graph->size);
 | 
				
			||||||
 | 
					    // 哈希表,用于记录已被访问过的顶点
 | 
				
			||||||
 | 
					    hashTable *visited = newHash(graph->size);
 | 
				
			||||||
 | 
					    dfs(graph, visited, startVet, res);
 | 
				
			||||||
 | 
					    // 释放哈希表内存并将数组索引归零
 | 
				
			||||||
 | 
					    freeHash(visited);
 | 
				
			||||||
 | 
					    resIndex = 0;
 | 
				
			||||||
 | 
					    // 返回遍历数组
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					    graphAdjList *graph = newGraphAdjList(10);
 | 
				
			||||||
 | 
					    for (int i = 0; i < 7; i++) {
 | 
				
			||||||
 | 
					        addVertex(graph, i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    addEdge(graph, 0, 1);
 | 
				
			||||||
 | 
					    addEdge(graph, 0, 3);
 | 
				
			||||||
 | 
					    addEdge(graph, 1, 2);
 | 
				
			||||||
 | 
					    addEdge(graph, 2, 5);
 | 
				
			||||||
 | 
					    addEdge(graph, 5, 4);
 | 
				
			||||||
 | 
					    addEdge(graph, 5, 6);
 | 
				
			||||||
 | 
					    printf("\n初始化后,图为:\n");
 | 
				
			||||||
 | 
					    printGraph(graph);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 深度优先遍历 DFS
 | 
				
			||||||
 | 
					    Vertex **vet = graphDFS(graph, graph->verticesList[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 输出遍历结果
 | 
				
			||||||
 | 
					    printf("\n深度优先遍历(DFS)顶点序列为\n");
 | 
				
			||||||
 | 
					    printf("[");
 | 
				
			||||||
 | 
					    printf("%d", vet[0]->val);
 | 
				
			||||||
 | 
					    for (int i = 1; i < graph->size && vet[i] != 0; i++) {
 | 
				
			||||||
 | 
					        printf(", %d", vet[i]->val);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf("]\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 释放内存
 | 
				
			||||||
 | 
					    free(vet);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user