十字链表的应用

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#define MAX_VERTEX_NUM 20
using namespace std;
typedef struct ArcBox{
    int tailVex, headVex;//该弧的尾和头顶点的位置
    struct ArcBox *hlink, *tlink;//分别为弧头相同和弧尾相同的弧的链域
    ArcBox(){
        hlink = NULL;
        tlink = NULL;
    }
} ArcBox; 

typedef struct VexNode{
    int data;
    ArcBox *firstin, *firstout;
    VexNode(){
        firstin = NULL;
        firstout = NULL;
    }
} VexNode; 

typedef struct{
    VexNode xlist[MAX_VERTEX_NUM];
    int vexnum, arcnum;
} OLGraph;

void buildG(OLGraph &g, int u, int v){
    ArcBox *p = new ArcBox;
    /*
        或者, new 方式可以调用类的构造函数
        ArcBox *p = (ArcBox *)malloc(sizeof(ArcBox));
        p->hlink = NULL;
        p->tlink = NULL;
    */
    p->tailVex = u;
    p->headVex = v;
    if(g.xlist[u].firstout == NULL){//在弧尾的地方插入
        g.xlist[u].firstout = p;
    } else {
        ArcBox *tmp = g.xlist[u].firstout;
        while(tmp->tlink) tmp = tmp->tlink;//找到和u节点相关的最后一个弧尾
        tmp->tlink = p;
    }

    if(g.xlist[v].firstin == NULL){//在弧头的地方插入
        g.xlist[v].firstin = p;
    } else {
        ArcBox *tmp = g.xlist[v].firstin;
        while(tmp->hlink) tmp = tmp->hlink;//找到和u节点相关的最后一个弧头
        tmp->hlink = p;
    }
}

void inG(OLGraph g){
    printf("从每一个节点出度方向遍历弧\n");
    for(int i=1; i<=g.vexnum; ++i){
        ArcBox *tmp = g.xlist[i].firstout;//找到弧尾节点为i的第一个节点
        printf("节点 %d:\n");
        while(tmp) {
            printf("弧 %d %d\n", tmp->tailVex, tmp->headVex);
            tmp = tmp->tlink;
        }
    }
}

void outG(OLGraph g){
    printf("每一个节点的入度方向遍历弧\n");
    for(int i=1; i<=g.vexnum; ++i){
        ArcBox *tmp = g.xlist[i].firstin;//找到弧头节点为i的第一个节点
        printf("节点 %d:\n");
        while(tmp) {
            printf("弧 %d %d\n", tmp->tailVex, tmp->headVex);
            tmp = tmp->hlink;
        }
    }
}

int main(){
    printf("请输入图的节点的个数和图的弧数:\n");
    OLGraph g;
    scanf("%d %d", &g.vexnum, &g.arcnum);
    printf("请输入图的弧:\n");
    for(int i=0; i<g.arcnum; ++i) {
        int u, v;
        scanf("%d %d", &u, &v);
        buildG(g, u, v);
    }
    //遍历方式,1.从每一个节点出度方向遍历弧 2.从每一个节点的入度方向遍历弧
    inG(g);
    printf("*****************\n");
    outG(g);
    return 0;
}

/*
有向图测试数据:
7
2
2
1
3
1
4
3 

*/
时间: 2024-08-31 19:02:06

十字链表的应用的相关文章

有向图的十字链表存储形式

十字链表是有向图的另一种链式存储结构.可以看成是将有向图的邻接表和逆邻接表(只考虑入度)结合起来得到的一种链表.在十字链表中,对应于有向图中每一个顶点有一个节点,每一条弧也有一个结点. 顶点之间是数组顺序存储,而弧是链式存储. 弧结点结构: 顶点结点结构: 十字链表形态:

大话数据结构二十:图的存储结构之十字链表

1. 引言: 对于有向图来说,邻接表是有缺陷的: 邻接表:关心了出度问题,想了解入度就必须要遍历整个图才知道. 逆邻接表:解决了入度,却不了解出度的情况. 能否把邻接表和逆邻接表结合起来呢?答案就是:使用十字链表. 2.十字链表存储结构: 顶点表结点结构: firstin:表示入边表头指针,指向该顶点的入边表中第一个结点. firstout:表示出边表头指针,指向该顶点的出边表中的第一个结点. 更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn

经典算法题每日演练——第二十一题 十字链表

     上一篇我们看了矩阵的顺序存储,这篇我们再看看一种链式存储方法"十字链表",当然目的都是一样,压缩空间. 一:概念     既然要用链表节点来模拟矩阵中的非零元素,肯定需要如下5个元素(row,col,val,down,right),其中: row:矩阵中的行. col:矩阵中的列. val:矩阵中的值. right:指向右侧的一个非零元素. down:指向下侧的一个非零元素. 现在我们知道单个节点该如何表示了,那么矩阵中同行的非零元素的表示不就是一个单链表吗?比如如下: 那么

十字链表的定义及C语言描述

十字链表常用于表示稀疏矩阵,可视作稀疏矩阵的一种链式表示,因此,这里以稀疏矩阵为背景介绍十字链表.不过,十字链表的应用远不止稀疏矩阵,一切具有正交关系的结构,都可用十字链表存储. 1.存储方式 (a)稀疏矩阵中每个非0元素对应一个十字链表结点,每个结点的结构为 其中各字段的含意为: row──元素在稀疏矩阵中的行号 col──元素在稀疏矩阵中的列号 val──元素值 down──指向同列中下一个非0元素结点 right──指向同行中下一个非0元素结点 (b)每行/列设一个表头结点(结构同元素结点

数据结构例程——稀疏矩阵的十字链表表示

本文针对数据结构基础系列网络课程(5):数组与广义表中第4课时稀疏矩阵的十字链表表示. 下面的程序中,实现了创建并显示十字链表的算法. #include <stdio.h> #include <malloc.h> #define M 3 //矩阵行 #define N 3 //矩阵列 #define Max ((M)>(N)?(M):(N)) //矩阵行列较大者 typedef int ElemType; typedef struct mtxn { int row; //行号

C 十字链表

C 的十字链表实现 #include<stdio.h> #include<stdlib.h> #include<conio.h> #include<string.h> #define MAX 20/*顶点的个数*/ typedef struct ArcBox{ int tailvex,headvex;/*弧的尾和头顶点位置*/ struct ArcBox *hlink,*tlink;/*分别为弧头相同弧尾相同的弧的链域*/ }ArcBox; typedef

顶点-有关图中十字链表的问题

问题描述 有关图中十字链表的问题 小弟刚刚看到图的十字链表,表示有点不明白为什么要这么复杂的数据结构,又要弧结点,又要顶点结点. 按照书本说的,假如就是邻接表和逆邻接表的结合,那为什么不在邻接表直接加个逆邻接表的指针呢?

输入矩阵的非邻元素建立十字链表并按行方式打印该十字链表的完整程序

/*   输入矩阵的非领元素建立十字链表并按行方式打印该十字链表的完整程序   */ struct matnode                             /* 十字链表结点的定义 */ {   int row,col;   struct matnode *right,*down;      union  {  int val;  struct matnode *next;      }tag; }; struct matnode *createmat() {   int m,n

Java中单向链表的实现:增删查改功能

写一个大家都比较熟悉的数据结构:单向链表. 不过先告诉大家一个小秘密,java的API里面已经提供了单向链表的类,大家可以直接拿来用,不过学习数据结构课程的时候想必大家也已经知道,虽然系统会给我们提供一些常用的数据结构,但是自定义的总是能够带来不同的喜感的,而且通过自己的编写也更能够让我们了解其中实现的过程,而且我们还可以写一些比较个性化的方法作为属于自己的数据结构.这里主要是介绍一些常用结构里面都会用到的方法,以及链表具体是如何操作的. 首先,单链表相对于队列的优势在于存储地址不是连续的,这样