赞
踩
橙色入度,绿色出度
代码示例:
- #include <stdio.h>
- #include <stdlib.h>
-
- // 定义十字链表节点结构体
- typedef struct OLNode {
- int row; // 行号
- int col; // 列号
- int value; // 节点值
- struct OLNode* right; // 指向右边节点的指针
- struct OLNode* down; // 指向下方节点的指针
- } OLNode, * OLink;
-
- // 定义十字链表的头节点结构体
- typedef struct {
- OLink* row_head; // 行表头指针数组
- OLink* col_head; // 列表头指针数组
- int m, n, len; // 矩阵的行数、列数和非零元素的个数
- } CrossList;
- // 创建十字链表
- CrossList CreateCrossList(int m, int n) {
- CrossList M;
- M.m = m;
- M.n = n;
- M.len = 0;
-
- // 初始化行和列的头指针数组
- M.row_head = (OLink*)malloc((m + 1) * sizeof(OLink));
- M.col_head = (OLink*)malloc((n + 1) * sizeof(OLink));
- if (!M.row_head || !M.col_head) {
- exit(1); // 内存分配失败
- }
-
- for (int i = 1; i <= m; i++) {
- M.row_head[i] = NULL;
- }
- for (int j = 1; j <= n; j++) {
- M.col_head[j] = NULL;
- }
-
- return M;
- }
- // 向十字链表插入元素
- void Insert(CrossList* M, int i, int j, int value) {
- if (i > M->m || j > M->n || value == 0) {
- return; // 插入位置不合法或值为0
- }
-
- // 创建新节点
- OLNode* newNode = (OLNode*)malloc(sizeof(OLNode));
- newNode->row = i;
- newNode->col = j;
- newNode->value = value;
- newNode->right = NULL;
- newNode->down = NULL;
-
- // 插入行
- if (M->row_head[i] == NULL) {
- M->row_head[i] = newNode;
- }
- else {
- OLNode* current = M->row_head[i];
- while (current->right && current->right->col < j) {
- current = current->right;
- }
- newNode->right = current->right;
- current->right = newNode;
- }
-
- // 插入列
- if (M->col_head[j] == NULL) {
- M->col_head[j] = newNode;
- }
- else {
- OLNode* current = M->col_head[j];
- while (current->down && current->down->row < i) {
- current = current->down;
- }
- newNode->down = current->down;
- current->down = newNode;
- }
-
- M->len++; // 更新非零元素个数
- }
- // 从十字链表删除元素
- void Delete(CrossList* M, int i, int j) {
- if (i > M->m || j > M->n) {
- return; // 位置不合法
- }
-
- // 查找要删除的节点
- OLNode* p = M->row_head[i];
- while (p && p->col < j) {
- p = p->right;
- }
-
- if (p && p->col == j) {
- // 删除行中的节点
- if (p == M->row_head[i]) {
- M->row_head[i] = p->right;
- }
- else {
- OLNode* q = M->row_head[i];
- while (q->right != p) {
- q = q->right;
- }
- q->right = p->right;
- }
-
- // 删除列中的节点
- if (p == M->col_head[j]) {
- M->col_head[j] = p->down;
- }
- else {
- OLNode* q = M->col_head[j];
- while (q->down != p) {
- q = q->down;
- }
- q->down = p->down;
- }
-
- free(p); // 释放节点内存
- M->len--; // 更新非零元素个数
- }
- }
- // 在十字链表中查找元素
- OLNode* Find(CrossList M, int i, int j) {
- if (i > M.m || j > M.n) {
- return NULL; // 位置不合法
- }
-
- OLNode* p = M.row_head[i];
- while (p && p->col < j) {
- p = p->right;
- }
-
- if (p && p->col == j) {
- return p; // 找到元素,返回节点指针
- }
- else {
- return NULL; // 未找到元素
- }
- }
- // 打印十字链表
- void PrintCrossList(CrossList M) {
- printf("十字链表如下:\n");
- for (int i = 1; i <= M.m; i++) {
- OLNode* p = M.row_head[i];
- while (p) {
- printf("(%d, %d, %d) ", p->row, p->col, p->value);
- p = p->right;
- }
- printf("\n");
- }
- }
- // 释放十字链表
- void FreeCrossList(CrossList* M) {
- for (int i = 1; i <= M->m; i++) {
- OLNode* p = M->row_head[i];
- while (p) {
- OLNode* q = p;
- p = p->right;
- free(q);
- }
- }
- free(M->row_head);
- free(M->col_head);
- }
- int main() {
- int m = 3, n = 4; // 定义一个3行4列的稀疏矩阵
- CrossList M = CreateCrossList(m, n); // 创建十字链表
-
- // 插入元素
- Insert(&M, 1, 2, 12);
- Insert(&M, 1, 4, 9);
- Insert(&M, 3, 1, -3);
- Insert(&M, 3, 3, 14);
-
- // 打印十字链表
- PrintCrossList(M);
-
- // 删除元素
- Delete(&M, 1, 2);
-
- // 再次打印十字链表
- printf("删除元素后的十字链表:\n");
- PrintCrossList(M);
-
- // 释放十字链表
- FreeCrossList(&M);
-
- return 0;
- }
-
优点:
每一条边只对应一个边结点,没有冗余数据,删除结点或者删除边的时候会方便很多
代码示例:
- #include <stdio.h>
- #include <stdlib.h>
-
- // 定义邻接多重表的边节点结构体
- typedef struct EdgeNode {
- int ivex; // 边的起点
- int jvex; // 边的终点
- struct EdgeNode* ilink; // 指向起点相同的下一条边
- struct EdgeNode* jlink; // 指向终点相同的下一条边
- int mark; // 标记边是否被访问过
- } EdgeNode;
-
- // 定义邻接多重表的顶点节点结构体
- typedef struct VertexNode {
- int data; // 顶点数据
- EdgeNode* firstedge; // 指向第一条依附于该顶点的边
- } VertexNode;
-
- // 定义邻接多重表结构体
- typedef struct {
- VertexNode* vertices; // 顶点表
- int vexnum, edgenum; // 顶点数和边数
- }AMLGraph;
- // 创建邻接多重表
- AMLGraph CreateAMLGraph(int vexnum, int edgenum) {
- AMLGraph graph;
- graph.vexnum = vexnum;
- graph.edgenum = edgenum;
-
- // 初始化顶点表
- graph.vertices = (VertexNode*)malloc(vexnum * sizeof(VertexNode));
- if (!graph.vertices) {
- exit(1); // 内存分配失败
- }
-
- for (int i = 0; i < vexnum; i++) {
- graph.vertices[i].data = i;
- graph.vertices[i].firstedge = NULL;
- }
-
- return graph;
- }
- // 插入边
- void InsertEdge(AMLGraph* graph, int ivex, int jvex) {
- // 创建边节点
- EdgeNode* newEdge = (EdgeNode*)malloc(sizeof(EdgeNode));
- newEdge->ivex = ivex;
- newEdge->jvex = jvex;
- newEdge->ilink = graph->vertices[ivex].firstedge;
- newEdge->jlink = graph->vertices[jvex].firstedge;
- newEdge->mark = 0;
-
- // 插入到顶点ivex的边表
- graph->vertices[ivex].firstedge = newEdge;
-
- // 插入到顶点jvex的边表
- graph->vertices[jvex].firstedge = newEdge;
- }
- // 删除边
- void DeleteEdge(AMLGraph* graph, int ivex, int jvex) {
- EdgeNode* p = graph->vertices[ivex].firstedge;
- EdgeNode* pre = NULL;
-
- while (p && (p->ivex != ivex || p->jvex != jvex)) {
- pre = p;
- if (p->ivex == ivex) {
- p = p->ilink;
- }
- else {
- p = p->jlink;
- }
- }
-
- if (p) {
- if (pre) {
- if (p->ivex == ivex) {
- pre->ilink = p->ilink;
- }
- else {
- pre->jlink = p->jlink;
- }
- }
- else {
- if (p->ivex == ivex) {
- graph->vertices[ivex].firstedge = p->ilink;
- }
- else {
- graph->vertices[jvex].firstedge = p->jlink;
- }
- }
- free(p);
- }
- }
- // 查找顶点
- VertexNode* FindVertex(AMLGraph graph, int data) {
- for (int i = 0; i < graph.vexnum; i++) {
- if (graph.vertices[i].data == data) {
- return &graph.vertices[i];
- }
- }
- return NULL;
- }
- // 打印邻接多重表
- void PrintAMLGraph(AMLGraph graph) {
- printf("邻接多重表如下:\n");
- for (int i = 0; i < graph.vexnum; i++) {
- EdgeNode* p = graph.vertices[i].firstedge;
- while (p) {
- int ivex = p->ivex;
- printf("(%d, %d) ", ivex, jvex);
- // 根据当前顶点,决定移动到ilink还是jlink
- if (ivex == i) {
- p = p->ilink;
- }
- else {
- p = p->jlink;
- }
- }
- printf("\n");
- }
- }
- // 释放邻接多重表
- void FreeAMLGraph(AMLGraph* graph) {
- for (int i = 0; i < graph->vexnum; i++) {
- EdgeNode* p = graph->vertices[i].firstedge;
- while (p) {
- EdgeNode* q = p;
- p = p->ilink;
- free(q);
- }
- }
- free(graph->vertices);
- }
- int main() {
- int vexnum = 4; // 定义顶点数为4
- int edgenum = 5; // 定义边数为5
- AMLGraph graph = CreateAMLGraph(vexnum, edgenum); // 创建邻接多重表
-
- // 插入边
- InsertEdge(&graph, 0, 1);
- InsertEdge(&graph, 0, 2);
- InsertEdge(&graph, 1, 2);
- InsertEdge(&graph, 1, 3);
- InsertEdge(&graph, 2, 3);
-
- // 打印邻接多重表
- PrintAMLGraph(graph);
-
- // 删除边
- DeleteEdge(&graph, 1, 2);
-
- // 再次打印邻接多重表
- printf("删除边后的邻接多重表:\n");
- PrintAMLGraph(graph);
-
- // 释放邻接多重表
- FreeAMLGraph(&graph);
-
- return 0;
- }
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。