zoukankan      html  css  js  c++  java
  • 链式前向星

    对于初学者来说前向星是不太好理解的,想当初蒟蒻的我就是怎么看都不明白,一直钟爱于邻接矩阵和邻接表

    but 作为一种特别的储存数据的结构,前向星有着其妙妙的作用,所以还是硬着头皮学吧

    我们首先来看一下什么是前向星.

    前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序,

    并记录下以某个点为起点的所有边在数组中的起始位置和存储长度,那么前向星就构造好了.

    用len[i]来记录所有以i为起点的边在数组中的存储长度.

    用head[i]记录以i为边集在数组中的第一个存储位置.

    那么对于下图:

    我们输入边的顺序为:

    1 2

    2 3

    3 4

    1 3

    4 1

    1 5

    4 5

    那么排完序后就得到:

    编号:     1      2      3      4      5      6      7

    起点u:    1      1      1      2      3      4      4

    终点v:    2      3      5      3      4      1      5

    得到:

    head[1] = 1    len[1] = 3

    head[2] = 4    len[2] = 1

    head[3] = 5    len[3] = 1

    head[4] = 6    len[4] = 2

    但是利用前向星会有排序操作,如果用快排时间至少为O(nlog(n)

    如果用链式前向星,就可以避免排序.

    我们建立边结构体为:

    1 struct Edge
    2 {
    3      int next;
    4      int to;
    5      int w;
    6 };

    其中edge[i].to表示第i条边的终点,edge[i].next表示与第i条边同起点的上

    另外还有一个数组head[],它是用来表示以i为起点的第一条边存储的位置,实际上你会发现这里的第一条边存储的位置其实

    在以i为起点的所有边的最后输入的那个编号.

    head[]数组一般初始化为-1,对于加边的add函数是这样的:

     1 #include<cstdio>
     2 using namespace std;
     3 struct sd{
     4   int to,w,next;  
     5 }edge[10005];
     6 int head[10005];//要先赋初值=-1;
     7 int num=0;
     8 void add(int a,int b,int w)
     9 {
    10     num++;
    11     edge[num].to=b;
    12     edge[num].w=w;
    13     edge[num].next=head[a];
    14     head[a]=num;
    15 }

    这样就可以基本实现图的加边操作。
    当然这个方法肯定不如链表,邻接矩阵好理解,但在许多图论与网络流题目中很实用。

  • 相关阅读:
    利用线程制作简单定时器
    VScode小白简介
    WebService介绍及C/C++访问
    Redis的C++与JavaScript访问操作
    Redis的安装配置及简单集群部署
    解决npm被墙的问题
    【学习整理】第三章 使用字符串
    【学习整理】第四章 字典
    【学习整理】第二章 列表和元祖
    【学习整理】第一章 基础知识部分 常用函数 简单语法
  • 原文地址:https://www.cnblogs.com/genius777/p/8470111.html
Copyright © 2011-2022 走看看