C语言中怎么实现图的存边
时间: 2024-05-13 15:17:09 浏览: 8
在C语言中,可以使用结构体数组来存储图的边信息。具体实现方法如下:
1. 定义一个结构体Edge表示图的一条边,包含起点、终点和权值等信息。
```
struct Edge {
int u; // 起点
int v; // 终点
int w; // 权值
};
```
2. 定义一个结构体数组graph[]来存储所有边的信息,其中数组的大小为边的数量。可以通过读取文件或者用户输入来确定边的数量。
```
int n; // 图的节点数
int m; // 图的边数
struct Edge graph[MAX_E]; // 存储所有边的信息
```
3. 读入每条边的信息,并将其存储到graph[]数组中。例如,可以通过循环读入每条边的起点、终点和权值,并将其赋值给graph[]数组对应的元素。
```
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &graph[i].u, &graph[i].v, &graph[i].w);
}
```
4. 在需要使用图的边信息时,可以遍历graph[]数组来访问每条边的属性。例如,可以通过以下方式访问第i条边的起点、终点和权值:
```
int u = graph[i].u;
int v = graph[i].v;
int w = graph[i].w;
```
相关问题
C语言结构体中存函数指针
在C语言中,结构体可以存储函数指针。这种用法通常被称为“函数指针成员”。通过在结构体中定义函数指针成员,可以将函数作为结构体的成员变量,并且可以通过该函数指针调用相应的函数。
下面是一个示例代码,展示了如何在C语言结构体中存储函数指针:
```c
#include <stdio.h>
// 定义一个函数指针类型
typedef void (*FuncPtr)(int);
// 定义一个结构体,包含一个函数指针成员
struct MyStruct {
FuncPtr func;
};
// 定义一个函数,用于作为函数指针的实现
void myFunction(int value) {
printf("Value: %d\n", value);
}
int main() {
// 创建一个结构体对象
struct MyStruct myStruct;
// 将函数指针赋值给结构体的函数指针成员
myStruct.func = myFunction;
// 调用结构体中存储的函数指针
myStruct.func(10);
return 0;
}
```
在上面的示例代码中,我们首先定义了一个函数指针类型`FuncPtr`,它可以指向一个接受一个`int`参数并返回`void`的函数。然后,我们定义了一个结构体`MyStruct`,其中包含一个名为`func`的函数指针成员。接下来,我们定义了一个函数`myFunction`,它与`FuncPtr`类型匹配。在`main`函数中,我们创建了一个`MyStruct`对象`myStruct`,并将`myFunction`赋值给了`myStruct`的`func`成员。最后,我们通过调用`myStruct.func(10)`来调用存储在结构体中的函数指针。
C语言实现连续分配外存分配方式代码
连续分配是一种外存分配方式,它的实现需要维护一个空闲空间链表和一个已分配空间链表,具体实现如下:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100 // 最大磁盘块数
/* 磁盘块结构体 */
typedef struct disk_block {
int is_free; // 该磁盘块是否空闲
int next; // 下一个磁盘块的位置
char data[512]; // 数据内容
} DiskBlock;
/* 磁盘结构体 */
typedef struct disk {
DiskBlock blocks[MAXSIZE];
int free_head; // 空闲空间链表头
int alloc_head; // 已分配空间链表头
} Disk;
/* 初始化磁盘 */
void init_disk(Disk *disk) {
disk->free_head = 0;
disk->alloc_head = -1;
for (int i = 0; i < MAXSIZE; i++) {
disk->blocks[i].is_free = 1;
disk->blocks[i].next = i + 1;
}
disk->blocks[MAXSIZE - 1].next = -1;
}
/* 分配磁盘块 */
int alloc_block(Disk *disk) {
if (disk->free_head == -1) { // 空闲空间链表为空
printf("No free block on disk!\n");
return -1;
}
int block_index = disk->free_head;
disk->free_head = disk->blocks[block_index].next;
disk->blocks[block_index].is_free = 0;
disk->blocks[block_index].next = -1;
if (disk->alloc_head == -1) { // 已分配空间链表为空
disk->alloc_head = block_index;
} else { // 已分配空间链表不为空
int p = disk->alloc_head;
while (disk->blocks[p].next != -1) {
p = disk->blocks[p].next;
}
disk->blocks[p].next = block_index;
}
return block_index;
}
/* 释放磁盘块 */
void free_block(Disk *disk, int block_index) {
if (disk->blocks[block_index].is_free == 1) { // 当前磁盘块已经空闲
printf("The block is already free!\n");
return;
}
disk->blocks[block_index].is_free = 1;
disk->blocks[block_index].next = disk->free_head;
disk->free_head = block_index;
if (block_index == disk->alloc_head) { // 释放的是已分配空间链表头
disk->alloc_head = disk->blocks[block_index].next;
} else { // 释放的是已分配空间链表中的其他节点
int p = disk->alloc_head;
while (disk->blocks[p].next != block_index) {
p = disk->blocks[p].next;
}
disk->blocks[p].next = disk->blocks[block_index].next;
}
}
int main() {
Disk disk;
init_disk(&disk);
int block1 = alloc_block(&disk);
int block2 = alloc_block(&disk);
int block3 = alloc_block(&disk);
printf("alloc_head: %d\n", disk.alloc_head);
printf("free_head: %d\n", disk.free_head);
free_block(&disk, block2);
printf("alloc_head: %d\n", disk.alloc_head);
printf("free_head: %d\n", disk.free_head);
return 0;
}
```
上述代码中,`DiskBlock` 结构体表示磁盘块,其中 `is_free` 表示该磁盘块是否空闲,`next` 表示下一个磁盘块的位置,`data` 表示数据内容。`Disk` 结构体表示整个磁盘,其中 `blocks` 表示磁盘块数组,`free_head` 表示空闲空间链表头,`alloc_head` 表示已分配空间链表头。
`init_disk` 函数用于初始化磁盘,将所有磁盘块标记为空闲状态,并建立空闲空间链表。`alloc_block` 函数用于分配磁盘块,从空闲空间链表中取出第一个空闲磁盘块,将其标记为已分配状态,并加入已分配空间链表中。`free_block` 函数用于释放磁盘块,将指定的磁盘块标记为空闲状态,并从已分配空间链表中删除,加入空闲空间链表中。
在 `main` 函数中,我们首先初始化磁盘,并分配了三个磁盘块。然后释放了第二个磁盘块,最后输出了已分配空间链表头和空闲空间链表头的位置。