数据结构-图(存储结构-十字链表)-C语言

对于有向图来说,邻接表是有缺陷的。关心了出度问题,想了解入度就必须要遍历整个图才能知道,反之,逆邻接表解决了入度却不了解出度的情况。有没有可能把邻接表与逆邻接表结合起来呢?答案是肯定的,就是把它们整合在一起。这就是我们现在要讲的有向图的一种存储方法:十字链表(Orthogonal List)。

如果想要更容易的理解十字链表法的代码,最好在这之前将邻接表和逆邻接表的代码都能自行实现。在好一点就是能将图的十字链表存储结构示意图画出来。

十字链表图示:
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

typedef char datatype;
typedef int edgetype;	//权值类型,建立网图时需引进 
#define MAXVEX 20	

typedef struct ENode
{
	int tailvex,headvex;	//弧起点在顶点表的下标,弧终点在顶点表的下标  
	struct ENode *taillink,*headlink;	//指向起点相同的下条边,指向终点相同的下条边
}EdgeNode;//边表结构 

typedef struct VNode
{
	datatype data;
	EdgeNode *firstin,*firstout;//入边表头指针 ,出边表头指针 
}VertexNode,OrtList[MAXVEX];//顶点结构 

typedef struct
{
	OrtList OrtList;		//储存所有的顶点的数组 
	int numVertexes,numEdges;//图中顶点数,边或弧的个数  
}GraphOrtList;//图结构--邻接表 

void Creat_GraphOrtList(GraphOrtList *G);
void Print_GraphOrtList(GraphOrtList G);

int main()
{
	GraphOrtList G;
	Creat_GraphOrtList(&G);
	Print_GraphOrtList(G);
}
//使用图的十字链表存储方式创建图  针对有向图的优化 
void Creat_GraphOrtList(GraphOrtList *G)
{
	int v_num,e_num;
	int i,x,y;
	EdgeNode *e;
	datatype ch;
	
	printf("Please input numVertexes,numEdges:");
	scanf("%d,%d",&v_num,&e_num);	//顶点个数 , 边或弧的个数
	G->numVertexes=v_num;
	G->numEdges=e_num;
	//给每个顶点赋值 
	for(i=0;i<v_num;i++)
	{
		printf("Please input adjList[%d].data:",i);
		scanf(" %c",&ch);
		G->OrtList[i].data=ch;
		G->OrtList[i].firstin=NULL;
		G->OrtList[i].firstout=NULL;	//入边表头指针,出边表头指针赋值NULL 
	}
	//建立边表 
	for(i=0;i<e_num;i++)
	{
		printf("Please input <vi,vj>的下标:\n");
		scanf(" %d,%d",&x,&y);
		e=(EdgeNode*)malloc(sizeof(EdgeNode));
		e->tailvex=x;
		e->headvex=y;
		//firstin:入边表头指针 firstout:出边表头指针
		e->taillink=G->OrtList[x].firstout;//taillink:指向起点相同的下条边
		G->OrtList[x].firstout=e;
		e->headlink=G->OrtList[y].firstin;//headlink:指向终点相同的下条边
		G->OrtList[y].firstin=e;
	}
	//n:顶点数,e:边数 时间复杂度--------->O(n+e) 
}
//打印十字链表 
void Print_GraphOrtList(GraphOrtList G)
{
	int i;
	EdgeNode *p;
    printf("邻接表为:\n");
    for(i=0;i<G.numVertexes;i++){
        p=G.OrtList[i].firstout;
        while(p){
            printf("(%c,%c)",G.OrtList[i].data,G.OrtList[p->headvex].data);
            p=p->taillink;
        }
        printf("\n");
    } 

    printf("逆邻接表为:\n");
    for(i=0;i<G.numVertexes;i++){
        p=G.OrtList[i].firstin;
        while(p){
            printf("(%c,%c)",G.OrtList[p->tailvex].data,G.OrtList[i].data);
            p=p->headlink;
        }
        printf("\n");
    } 
}

输出结果:
在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值