图->存储结构->十字链表
文字描述
十字链表是有向图的另一种链式存储结构. 在十字链表中,对应于有向图中每一条弧有一个结点,对应于每个顶点也有一个结点.这些结点的结构如下所示:
在弧结点中有5个域: 尾域tailvex和头域headvex分别指示弧尾和弧头这两个顶点在图中的位置,链域hlink指向与弧头相同的下一条弧, 而链域tlink指向弧尾相同的下一条弧, info域指向该弧的相关信息; 弧头相同的弧在同一链表上, 弧尾相同的弧也在同一链表上. 它们的头结点即为顶点结点,它由3个域组成:其中data域存储和顶点相关的信息,如顶点名称等; firstin和firstout为两个链域,分别指向以该顶点为弧头或弧尾的第一个弧结点.
示意图
算法分析
建立十字链表的时间复杂度和建立邻接表是相同的. 而且在十字链表中既容易找到以vi为尾的弧,也容易找到以vi为头的弧,因而容易求得顶点的出度和入度.
代码实现
/*
以十字链表作为图的存储结构创建图。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #define MAX_VERTEX_NUM 20 //最大顶点数
#define DEBUG
typedef enum {DG, DN, UDG, UDN} GraphKind; //{有向图,有向网,无向图,无向网}
typedef char InfoType;
typedef char VertexType;
//弧结点
typedef struct ArcBox{
int tailvex, headvex;//该弧的尾和头顶点的位置
struct ArcBox *hlink, *tlink;//分别为弧头相同和弧尾相同的弧的链域
InfoType *info;//该弧相关的信息
}ArcBox;
//顶点结点
typedef struct VexNode{
VertexType data;//顶点名称
ArcBox *firstin, *firstout;//分别指向该顶点第一条入弧和出弧
}VexNode;
typedef struct{
VexNode xlist[MAX_VERTEX_NUM];//表头向量
int vexnum, arcnum;//有向图的当前顶点数和弧数
GraphKind kind;//图类型
}OLGraph; /*
若G中存在顶点u,则返回该顶点在图中位置;否则返回-1。
*/
int LocateVex(OLGraph G, VertexType v)
{
int i = ;
for(i=; i<G.vexnum; i++){
if(G.xlist[i].data == v)
return i;
}
return -;
} /*
若G中存在顶点位置loc存在,则返回其顶点名称
*/
VertexType LocateVInfo(OLGraph G, int loc)
{
return G.xlist[loc].data;
} /*
采用十字链表的存储结构,构造有向图
*/
int CreateDG(OLGraph *G)
{
int i = , j = , k = , IncInfo = ;
int v1 = , v2 = ;
char tmp[] = {};
ArcBox *p = NULL; printf("输入顶点数,弧数,其他信息标志位: ");
scanf("%d,%d,%d", &G->vexnum, &G->arcnum, &IncInfo); for(i=; i<G->vexnum; i++){
//输入顶点值
printf("输入第%d个顶点: ", i+);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
//初始化指针
G->xlist[i].data = tmp[];
G->xlist[i].firstin = NULL;
G->xlist[i].firstout = NULL;
} //输入各弧并构造十字链表
for(k=; k<G->arcnum; k++){
printf("输入第%d条弧(顶点1, 顶点2): ", k+);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
sscanf(tmp, "%c,%c", &v1, &v2);
//确定顶点v1和v2在图中的位置
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
//对弧结点赋值
p = (ArcBox *) malloc(sizeof(ArcBox));
p->tailvex = i;
p->headvex = j;
p->hlink = G->xlist[j].firstin;
p->tlink = G->xlist[i].firstout;
p->info = NULL;
//完成在入弧和出弧链头的插入
G->xlist[j].firstin = p;
G->xlist[i].firstout = p;
//若弧有相关的信息,则输入
if(IncInfo){
//Input(p->info);
}
}
return ;
} /*
采用十字链表的存储结构,构造图
*/
int CreateGraph(OLGraph *G)
{
printf("输入图类型: +有向图(0), -有向网(1), -无向图(2), -无向网(3): ");
scanf("%d", &G->kind);
switch(G->kind){
case DG:
return CreateDG(G);
case DN:
case UDN:
case UDG:
default:
printf("还不支持!\n");
return -;
}
} /*
输出图的信息
*/
void printG(OLGraph G)
{
if(G.kind == DG){
printf("类型:有向图;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}else if(G.kind == DN){
printf("类型:有向网;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}else if(G.kind == UDG){
printf("类型:无向图;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}else if(G.kind == UDN){
printf("类型:无向网;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
} int i = ;
ArcBox *fi = NULL;
ArcBox *fo = NULL;
for(i=; i<G.vexnum; i++){
printf("%c: ", G.xlist[i].data);
fi = G.xlist[i].firstin;
fo = G.xlist[i].firstout;
printf("(hlink=");
while(fi){
#ifdef DEBUG
printf("%c->%c; ", LocateVInfo(G, fi->tailvex), LocateVInfo(G, fi->headvex));
#else
printf("%d->%d; ", fi->tailvex, fi->headvex);
#endif
fi = fi->hlink;
}
printf(")\t(tlink=");
while(fo){
#ifdef DEBUG
printf("%c->%c; ", LocateVInfo(G, fo->tailvex), LocateVInfo(G, fo->headvex));
#else
printf("%d->%d; ", fo->tailvex, fo->headvex);
#endif
fo = fo->tlink;
}
printf(")\n");
}
return;
} int main(int argc, char *argv[])
{
OLGraph G;
if(CreateGraph(&G) > -){
printG(G);
}
return ;
}
十字链表存储结构(图)
代码运行
图->存储结构->十字链表的更多相关文章
- 图->存储结构->邻接多重表
文字描述 邻接多重表是无向图的另一种链式存储结构. 虽然邻接表是无向图的一种很有效的存储结构,在邻接表中容易求得顶点和边的各种信息. 但是,在邻接表中每一条边(vi,vj)有两个结点,分别在第i个和第 ...
- 图->存储结构->邻接表
文字描述 邻接表是图的一种链式存储结构.在邻接表中,对图中每个顶点建立一个单链表,第i个单链表的结点表示依附顶点vi的边(对有向图是指以顶点vi为尾的弧).单链表中的每个结点由3个域组成,其中邻接点域 ...
- 图->存储结构->数组表示法(邻接矩阵)
文字描述 用两个数组分别存储顶点信息和边/弧信息. 示意图 算法分析 构造一个采用邻接矩阵作存储结构.具有n个顶点和e条边的无向网(图)G的时间复杂度是(n*n + e*n), 其中对邻接矩阵G.ar ...
- 图的存储结构与操作--C语言实现
图(graph)是一种比树结构还要复杂的数据结构,它的术语,存储方式,遍历方式,用途都比较广,所以如果想要一次性完成所有的代码,那代码会非常长.所以,我将分两次来完成图的代码.这一次,我会完成图的五种 ...
- 算法与数据结构(四) 图的物理存储结构与深搜、广搜(Swift版)
开门见山,本篇博客就介绍图相关的东西.图其实就是树结构的升级版.上篇博客我们聊了树的一种,在后边的博客中我们还会介绍其他类型的树,比如红黑树,B树等等,以及这些树结构的应用.本篇博客我们就讲图的存储结 ...
- C语言实现链表(链式存储结构)
链表(链式存储结构)及创建 链表,别名链式存储结构或单链表,用于存储逻辑关系为 "一对一" 的数据.与顺序表不同,链表不限制数据的物理存储状态,换句话说,使用链表存储的数据元素,其 ...
- javascript实现数据结构:线性表--线性链表(链式存储结构)
上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...
- Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析
Hashtable 是一个很常见的数据结构类型,前段时间阿里的面试官说只要搞懂了HashTable,hashMap,HashSet,treeMap,treeSet这几个数据结构,阿里的数据结构面试没问 ...
- 树和二叉树->存储结构
文字描述 1 二叉树的顺序存储 用一组地址连续的存储单元自上而下,自左至右存储完全二叉树上的结点元素. 这种顺序存储只适用于完全二叉树.因为,在最坏情况下,一个深度为k且只有k个结点的单支树却需要长度 ...
随机推荐
- 腾讯云快速完成python3.6开发环境搭建与django应用部署
[本文出自天外归云的博客园] 部署python3.6.5 腾讯云服务器安装python3竟然要3个多小时!而且一度速度为0…… 于是网查据说是腾讯云服务器连python官网缓慢导致的,所以想找个国内的 ...
- [转]bootstrap table 动态列数
原文地址:https://my.oschina.net/u/2356355/blog/1595563 据说bootstrap table非常好用,从入门教程中了解到它的以下主要功能: 由于固定表头意味 ...
- CentOS 添加 Oracle YUM 源
最新文章:Virson's Blog 文章来自:Oracle 官方 YUM 源 Introduction The Oracle public yum server offers a free and ...
- mycat 9066管理端口
1.连接mycat 9066管理端口 命令:mysql -uroot -proot -P9066 -h127.0.0.1 -u:用户名 -p:密码 -P:端口 -h:ip地址例:linux路径切换到m ...
- 二、主流区块链技术特点及Hyperledger Fabric V0.6版本特点
一.主流区块链技术特点 二.HyperLedger子项目 三.Hyperledger fabric架构 V0.6逻辑架构: V0.6区块链网络 对应的0.6版本的运行时架构: 0.6版本的架构特点是: ...
- Java8学习笔记(六)--Optional
前言 身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只有在非空的前提下才能将其作为其他方法的 ...
- SpringBatch的初步了解
一.SpringBatch是一个批处理的框架,作为一个Spring组件,提供了通过使用Spring的依赖注入来处理批处理的条件. 什么是批处理呢? 在现代企业应用当中,面对复杂的业务以及海量的数据,除 ...
- 使用Sublime Text搭建python调试环境[转]
pycharmt等IDE虽然用着爽,但毕竟在速度.资源上还是比较让人不爽的. 使用IDE无非是图个方便省事,特别是像我这种有些记性差的来说. IDE说起来方便于的几个地方就是: 1.语法颜色高亮 2. ...
- sencha touch 带本地搜索功能的selectfield(选择插件)
带本地搜索功能的选择插件,效果图: 在使用selectfield的过程中,数据过大时,数据加载缓慢,没有模糊查询用户体验也不好, 在selectfield的基础上上稍作修改而成,使用方式同select ...
- 【CF582E】Boolean Function 树形DP+FWT
[CF582E]Boolean Function 题意:给你一个长度为n的表达式,其中未知数有A,B,C,D和?,运算有&和|和?(表达式中用括号确定了唯一的运算顺序).?代表A,B,C,D或 ...