C语言数据结构、十字链表的分析及实现

目录

前言

一、什么是十字链表

二、认识十字链表

1.十字链表的组成

2.顶点和弧的连接

三、代码逻辑实现

1.出度

 2.入度

总结



前言

  无论是什么程序都要和数据打交道,一个好的程序员会选择更优的数据结构来更好的解决问题,因此数据结构的重要性不言而喻。数据结构的学习本质上是让我们能见到很多前辈在解决一些要求时间和空间的难点问题上设计出的一系列解决方法,我们可以在今后借鉴这些方法,也可以根据这些方法在遇到具体的新问题时提出自己的解决方法。(所以各种定义等字眼就不用过度深究啦,每个人的表达方式不一样而已),在此以下的所有代码都是仅供参考,并不是唯一的答案,只要逻辑上能行的通,写出来的代码能达到相同的结果,并且在复杂度上差不多,就行了。


一、什么是十字链表

在上篇文章的最后,我们分析了邻接表的优劣,邻接表本身并没有什么大的缺陷,如果说有缺点,那么是对于有向图而言对同时表示一个顶点的出度和入度麻烦,因为需要有邻接表和逆邻接表同时表示,而且这种应用场景是存在的。十字链表就是为了使这个问题得到解决而出现的。

所以十字链表就是一种将邻接表和逆邻接表结合在一起的一种图的存储结构,它针对的就是有向图中出度和入度一起使用的情况,并且大大节省了内存。

二、认识十字链表

1.十字链表的组成

十字链表是由数组+链表的形式构成的,数组用来记录顶点的信息,链表用来记录弧(边)的信息。

在有向图中,顶点集的存储结构如下图所示

其中data是数据域,用于记录顶点的信息,而firstIn和firstOut是两个指针,指向的是以该节点为弧头(In)或弧尾(Out)的第一节点。

 对于如此一个有向图而言,弧头和弧尾的概念是人为设置的,在这里我们假定一个顶点的入度指向弧头,出度的方向为弧尾

 它的顶点数组应该这么表示,为了方便讲解,这里我们假定输入的值就是对应的下标,实际上应该通过用户输入的值在顶点数组中找到对应的下标

代码实现

//顶点集
typedef struct VexNode
{
    //数据域
    int data;
    ArcBox* firstIn, *firstOut;//以该节点为弧头或弧尾的首节点
}VexNode;

 在有向图中每一个顶点与之对应的弧,具体的弧的存储结构如下所示

  • 12
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
稀疏矩阵的十字链表是一种用于压缩稀疏矩阵的数据结构。它通过链表的方式来存储矩阵中非零元素的位置和值,并且可以快速地进行插入和删除操作。在C语言中,可以使用结构体和指针来实现稀疏矩阵的十字链表。具体实现如下: ``` #include <stdio.h> #include <stdlib.h> typedef struct Node { int row; int col; int value; struct Node* right; struct Node* down; } Node; typedef struct CrossList { Node* rhead; Node* chead; int rows; int cols; int nums; } CrossList; void InitCrossList(CrossList* crosslist, int rows, int cols); void InsertCrossList(CrossList* crosslist, int row, int col, int value); void PrintCrossList(CrossList* crosslist); void InitCrossList(CrossList* crosslist, int rows, int cols) { crosslist->rhead = (Node*)malloc(sizeof(Node) * rows); crosslist->chead = (Node*)malloc(sizeof(Node) * cols); crosslist->rows = rows; crosslist->cols = cols; crosslist->nums = 0; for (int i = 0; i < rows; i++) { crosslist->rhead[i].right = NULL; } for (int i = 0; i < cols; i++) { crosslist->chead[i].down = NULL; } } void InsertCrossList(CrossList* crosslist, int row, int col, int value) { if (row >= crosslist->rows || col >= crosslist->cols) { return; } Node* node = (Node*)malloc(sizeof(Node)); node->row = row; node->col = col; node->value = value; Node* p = &crosslist->rhead[row]; while (p->right && p->right->col < col) { p = p->right; } if (p->right && p->right->col == col) { p->right->value = value; free(node); } else { node->right = p->right; p->right = node; } p = &crosslist->chead[col]; while (p->down && p->down->row < row) { p = p->down; } if (p->down && p->down->row == row) { p->down->value = value; } else { node->down = p->down; p->down = node; } crosslist->nums++; } void PrintCrossList(CrossList* crosslist) { printf("稀疏矩阵的十字链表表示:\n"); for (int i = 0; i < crosslist->rows; i++) { Node* p = crosslist->rhead[i].right; for (int j = 0; j < crosslist->cols; j++) { if (p && p->col == j) { printf("%d ", p->value); p = p->right; } else { printf("0 "); } } printf("\n"); } } int main() { CrossList crosslist; int rows, cols; printf("请输入稀疏矩阵的行数和列数:"); scanf("%d %d", &rows, &cols); InitCrossList(&crosslist, rows, cols); int row, col, value; printf("请输入稀疏矩阵中非零元素的行、列和值(以-1 -1 -1结束):\n"); while (1) { scanf("%d %d %d", &row, &col, &value); if (row == -1 && col == -1 && value == -1) { break; } InsertCrossList(&crosslist, row, col, value); } PrintCrossList(&crosslist); return 0; } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小白还在写代码

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

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

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

打赏作者

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

抵扣说明:

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

余额充值