图的存储和串的匹配

一、图的四种存储方式

复制代码
//下面是图的存储
//(1)邻接矩阵法
#define MaxVertexNum 100
typedef char VertexType;
typedef int EdgeType;
typedef struct
{
    VertexType Vex[MaxVertexNum];//顶点表
    EdgeType Edge[MaxVertexNum][MaxVertexNum];//邻接矩阵,边表
    int vexnum, arcnum;//图的当前顶点数和弧数
}MGraph;

//(2)邻接表存储
typedef struct ArcNode//边表结点
{
    int adjvex;//该弧所指向的顶点的位置
    struct ArcNode* next;//指向下一条弧的指针
}ArcNode;
typedef struct VNode//顶点表节点
{
    VertexType data;//顶点信息
    ArcNode* first;//指向第一条依附该顶点的弧的指针
}VNode, AdjList[MaxVertexNum];
typedef struct
{
    AdjList vertices;//邻接表
    int vexnum, arcnum;//图的顶点数和弧数
}ALGraph;//以邻接表存储的图类型

//(3)十字链表
typedef struct ArcNode//边表结点
{
    int tailvex, headvex;//该弧的头尾结点
    struct ArcNode* hlink, * tlink;//分别指向弧头相同和弧尾相同的结点
}ArcNode;
typedef struct VNode//顶点表结点
{
    VertexType data;//顶点信息
    ArcNode* firstin, * firstout;//指向第一条入弧和出弧
}VNode;
typedef struct
{
    VNode xlist[MaxVertexNum];//邻接表
    int vexnum, arcnum;//图的顶点数和弧数
}GLGraph;

//(4)邻接多重表
typedef struct ArcNode
{
    bool mark;//访问标记
    int ivex, jvex;//分别指向该弧的两个结点
    struct ArcNode* ilink, * jlink;//分别指向两个顶点的下一条边
}ArcNode;
typedef struct VNode//顶点表结点
{
    VertexType data;//顶点信息
    ArcNode* firstedge;//指向第一条依附该顶点的边
}VNode;
typedef struct
{
    VNode adjmulist[MaxVertexNum];//邻接表
    int vexnum, arcnum;//图的顶点数和弧数
}AMLGraph;
复制代码

二、串的匹配方式

复制代码
//子串的定位操作通常叫做串的模式匹配,它求的是子串(常称模式串)在主串中的位置
//(1)利用串的其他基本操作给出定位操作的一种算法
int Index(string S, string T, int pos)
{
    if (pos > 0)
    {
        int n = strlen(S);
        int m = strlen(T);
        int i = pos;
        while (i < n - m + 1)
        {
            substring(sub, S, i, m);
            if (strcompare(sub, T) != 0)
                ++i;
            else
                return i;
        }
        return 0;
    }
}
//不依赖于其他串操作的暴力算法
int Index(String S, String T, int pos)
{
    int i = pos, j = 1;
    while(i <= S.length && j <= T.length)
    {
        if (S.ch[i] == T.ch[j])
        {
            ++i;
            ++j;//继续比较后继字符
        }
        else
        {
            i = i - j + 2;
            j = 1;//指针后退重新开始匹配
        }
    }
    if (j > T.length)
        return i - T.length;
    else
        return 0;
}

//KMP算法重要的3个概念:前缀、后缀、部分匹配值(字符串的前缀和后缀的最长相等前后缀长度)
//现在变成子串向后移动,主串不移动
//移动尾数=已匹配的字符数-对应的部分匹配值
//Move = (j - 1) - next[j - 1];
void get_next(string T, int next[])
{
    int i = 1, j = 0;
    next[1] = 0;
    while (i < T.length)
    {
        if (j == 0 || T.ch[i] == T.ch[j])
        {
            ++i;
            ++j;
            next[i] = j;
        }
        else
        {
            j = next[j];
        }
    }
}
/*
和next数组的计算相比,KMP匹配算法相对要简单得多,它在形式上和简单的模式匹配算法很相似。
不同之处仅仅在于当匹配过程产生失配的时候,指针i不变,指针j退回到next[j]的位置并重新进行比较
并且当指针j为0时,指针i和j同时加1
若主串的第i个位置和模式串的第一个字符不等,则应从主串的第i+1个位置开始匹配
*/
int Index_KMP(string S, string T, int next[], int pos)
{
    int i = pos, j = 1;
    while (i <= S.length && j <= T.length)
    {
        if (j == 0 || S.ch[i] == T.ch[j])
        {
            ++i;
            ++j;//继续比较后续字符
        }
        else
            j = next[j];//模式串向后移动
    }
    if (j > T.length)
        return i - T.length;//匹配成功
    else return 0;
}
复制代码

 

posted @   花与不易  阅读(76)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示