数据结构——图的基本操作

数据结构——图的基本操作

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


///*图的结构定义============*///
#define MAX 500
typedef struct arcnode
{
    int adjvex;
    struct arcnode *next;
    int value;
} arcnode;
typedef struct vnode
{
    int date;
    arcnode *firstac;
} vnode;
typedef struct
{
    vnode vlist[MAX];
    int vexnum,arcnum;
    int kind;
} algraph;
///*-------------------------*///


///*队列链式的实现==============*///
typedef int elem;
typedef struct queueNode{
    elem data;
    struct queueNode* next;
}queueNode;
queueNode* initQueue(queueNode *head)
{
    head = (queueNode*)malloc(sizeof(queueNode));
    if(!head) exit(0);
    head->next = NULL;
    return head;
}
queueNode* enQueue(queueNode* head,elem data)
{
    queueNode* p = (queueNode*)malloc(sizeof(queueNode));
    if(!p) exit(0);
    p->data = data;
    p->next = NULL;

    queueNode* pr = head;
    while(pr->next)
    {
        pr = pr->next;
    }
    pr->next = p;
    return head;
}
elem deQueue(queueNode* head)
{
    if(!head->next) return -1;

    queueNode* p = head->next;
    elem temp = p->data;
    head->next = p->next;
    free(p);

    return temp;
}
int empty(queueNode* head)
{
    return head->next ? 0 : 1;
}
///*========================*///


//图的创建 noProblem
void creGraph(algraph* al)
{
    int i,j;

    scanf("%d%d%d",&al->kind,&al->vexnum,&al->arcnum);
    for(i = 0; i < al->vexnum; i ++)
    {
        scanf("%d",&al->vlist[i].date);
        al->vlist[i].firstac = NULL;

    }
    for(j = 0; j < al->arcnum; j ++)
    {
        int a,b;
        scanf("%d %d",&a,&b);

        arcnode* p = (arcnode*)malloc(sizeof(arcnode));
        p->next = NULL;
        for(i = 0; i < al->vexnum; i ++)
        {
            if(al->vlist[i].date == b)
            {
                p->adjvex = i;
                break;
            }
        }
        for(i = 0; i < al->vexnum; i ++)
        {
            if(al->vlist[i].date == a)
            {
                arcnode* pr = al->vlist[i].firstac;
                if(!pr)
                {
                    al->vlist[i].firstac = p;
                    break;
                }

                while(pr->next) pr = pr->next;
                pr->next = p;

                break;
            }
        }
    }
    printf("UDG has been created successfully.\n");
}
//输出邻接表  noProblem
void printList(algraph *al)
{
    putchar('\n');
    int i;
    for(i = 0;i < al->vexnum;i ++)
    {
        printf("jiedian:%d ",al->vlist[i].date);

        arcnode *p = al->vlist[i].firstac;
        while(p)
        {
            printf("next:%d value:%d ",p->adjvex,p->value);
            p = p->next;
        }
        putchar('\n');
    }
}
//销毁图
void desGraph(algraph* al)
{
    int i;
    for(i = 0;i < al->vexnum;i ++)
    {
        arcnode* pr = al->vlist[i].firstac;
        arcnode* p =NULL;

        while(pr)
        {
            p = pr;
            pr = pr->next;
            free(p);
        }
        free(&al->vlist[i].date);
    }
    al->arcnum = 0;
    al->vexnum = 0;
    al->kind = -1;
}
//查找节点图中的下标  noProblem
int local(algraph* al,int ch)
{
    int i;
    for(i = 0; i < al->vexnum; i ++)
    {
        if(al->vlist[i].date == ch)
            return i;
    }
    printf("顶点输入错误!!!");
    return -1;
}
//返回特定节点的值 noProblem
int GetVex(algraph* al,int v)
{
    int i;
    for(i = 0;i < al->vexnum;i ++)
    {
        arcnode* p = al->vlist[i].firstac;
        while(p)
        {
            if(p->adjvex == v)
            {
                return p->value;
            }
            p = p->next;
        }
    }
    return -1;
}
//对图中的节点v赋值 noProblem
void PutVexing(algraph* al,int v,int value)
{
    int i;
    for(i = 0;i < al->vexnum;i ++)
    {
        arcnode *p = al->vlist[i].firstac;
        while(p)
        {
            if(p->adjvex == v)
            {
                p->value = value;
            }
            p = p->next;
        }
    }
}
//求图中顶点v的第一个邻接顶点 noProblem
void FirdtAdjVexf(algraph* al,int v)
{
    int i;
    for(i = 0;i < al->vexnum;i ++)
    {
        if(al->vlist[i].date == v)
        {
            printf("FirstNext:%d",al->vlist[i].firstac->adjvex);
        }
    }
}
//在图中新增添节点v
void InsertVex(algraph* al,int v)
{
    al->vlist[al->vexnum].date = v;
    al->vlist[al->vexnum].firstac = NULL;

    al->vexnum ++;
}
//在图中增添弧,如果是无向的,还应添加对称点 noProblem
//1.有向图 2.无向图 3.有向网 4.无向网
void InsertArc(algraph* al,int v,int w)
{
    int i ;
    arcnode* p = (arcnode*)malloc(sizeof(arcnode));
    if(!p) exit(0);

    p->adjvex = w;
    for(i = 0;i < al->vexnum;i ++)
    {
        if(al->vlist[i].date == v)
        {
            p->next = al->vlist[i].firstac;
            al->vlist[i].firstac = p;
            al->arcnum ++;
            break;
        }
    }
    if(al->kind == 2 || al->kind == 4)
    {
        arcnode* pr = (arcnode*)malloc(sizeof(arcnode));
        if(!pr) exit(0);

        pr->adjvex = v;
        for(i = 0;i < al->vexnum;i ++)
        {
            if(al->vlist[i].date == w)
            {
                pr->next = al->vlist[i].firstac;
                al->vlist[i].firstac = pr;
                al->arcnum ++;
                break;
            }
        }
    }
}
//删除顶点v即相关的弧  noProblem
void DeleteVex(algraph* al,int v)
{
    int i,j;
    for(i = 0;i < al->vexnum;i ++)
    {
        if(al->vlist[i].date == v)
        {
            for(j = i;j < al->vexnum - 1;j ++)
            {
                al->vlist[j] = al->vlist[j + 1];
            }
            al->vexnum --;
            break;
        }
    }
    for(i = 0;i < al->vexnum;i ++)
    {
        arcnode* pr = al->vlist[i].firstac;
        arcnode* p = al->vlist[i].firstac;
        while(pr)
        {
            if(pr->adjvex == v)
            {
                if(p == pr)//第一个节点符合条件时
                {
                    al->vlist[i].firstac = pr->next;
                    free(pr);
                    al->arcnum --;
                    break;
                }
               p->next = pr->next;
               free(pr);
               al->arcnum --;
               break;
            }
            p = pr;
            pr = pr->next;
        }
    }
}
//删除弧,如果是无向的,还要删除对称弧  noProblem
void DeleteArc(algraph* al,int v,int w)
{
    int i;
    int vIndex,wIndex;
    for(i = 0;i < al->vexnum;i ++)
    {
        if(al->vlist[i].date == v)
            vIndex = i;
        if(al->vlist[i].date == w)
            wIndex = i;
    }

    arcnode *p = al->vlist[vIndex].firstac;
    arcnode *pr = al->vlist[vIndex].firstac;
    while(p)
    {

        if(p->adjvex == wIndex)
        {
            if(p == pr)
            {
                al->vlist[vIndex].firstac = p->next;
                free(p);
                al->arcnum --;
                break;
            }
            pr->next = p->next;
            free(p);
            al->arcnum --;
            break;
        }
        pr = p;
        p = p->next;
    }
    if(al->kind == 2 || al->kind == 4)
    {
        p = al->vlist[wIndex].firstac;
        pr = al->vlist[wIndex].firstac;
        while(p)
        {
            if(p->adjvex == vIndex)
            {
                if(p == pr)
                {
                    al->vlist[wIndex].firstac = p->next;
                    free(p);
                    al->arcnum --;
                    break;
                }
                pr->next = p->next;
                free(p);
                al->arcnum --;
                break;
            }
            pr = p;
            p = p->next;
        }
    }
}
//深度优先遍历 noProblem
void dnf(algraph* al,int i);
int visited[MAX];
void dnfTrave(algraph* al)
{
    int i;
    for(i = 0; i < al->vexnum; i ++)
        visited[i] = 0;
    for(i = 0; i < al->vexnum; i ++)
        if(!visited[i]) dnf(al,i);
}
void dnf(algraph* al,int i)
{
    visited[i] = 1;
    printf("%d ",al->vlist[i].date);

    arcnode *p = al->vlist[i].firstac;
    while(p)
    {
        if(!visited[p->adjvex])
            dnf(al,p->adjvex);
        p = p->next;
    }
}
//广度优先遍历 noProblem
void BFSTraverse(algraph* al)
{
    int i;
    for(i = 0;i < al->vexnum;i ++)
        visited[i] = 0;

    queueNode* head = NULL;
    head = initQueue(head);

    for(i = 0;i < al->vexnum;i ++)
    {
        if(!visited[i])
        {
            visited[i] = 1;
            printf("%d ",al->vlist[i].date);
            head = enQueue(head,i);

            while(!empty(head))
            {
                arcnode *p = al->vlist[deQueue(head)].firstac;
                while(p)
                {
                    if(!visited[p->adjvex])
                    {
                        visited[p->adjvex] = 1;
                        printf("%d ",al->vlist[p->adjvex].date);
                        head = enQueue(head,p->adjvex);
                    }
                    p = p->next;
                }
            }
        }
    }

}
//求顶点v的度 noProblem
int FindDegree(algraph* al,int v)
{
    int count = 0;
    int i = 0;
    int vIndex;
    arcnode *p = NULL;

    for(i = 0;i < al->vexnum;i ++)
    {
        if(al->vlist[i].date == v)
        {
            vIndex = i;
            break;
        }
    }
    for(i = 0;i < al->vexnum;i ++)
    {
        p = al->vlist[i].firstac;
        while(p)
        {
            if(p->adjvex == vIndex)
            {
                count ++;
                break;
            }
            p = p->next;
        }
    }
    p = al->vlist[vIndex].firstac;
    while(p)
    {
        count ++;
        p = p->next;
    }
    return count;
}
//计算出度
int FindOutDegree(algraph* al,int v)
{
    int count = 0;
    int i = 0;
    int vIndex;
    arcnode *p = NULL;

    for(i = 0;i < al->vexnum;i ++)
    {
        if(al->vlist[i].date == v)
        {
            vIndex = i;
            break;
        }
    }
    p = al->vlist[vIndex].firstac;
    while(p)
    {
        count ++;
        p = p->next;
    }
    return count;
}
//求有向图中顶点v的入度
int FindInDegree(algraph* al,int v)
{
    int count = 0;
    int i = 0;
    int vIndex = -1;
    arcnode *p = NULL;

    for(i = 0;i < al->vexnum;i ++)
    {
        if(al->vlist[i].date == v)
        {
            vIndex = i;
            break;
        }
    }
    if(vIndex == -1) printf("节点入度计算错误,没有该节点");
    for(i = 0;i < al->vexnum;i ++)
    {
        p = al->vlist[i].firstac;
        while(p)
        {
            if(p->adjvex == vIndex)
            {
                count ++;
                break;
            }
            p = p->next;
        }
    }
    return count;
}
int main()
{
    algraph al;
    creGraph(&al);
    
    printf("DFS traverse: ");
    dnfTrave(&al);
    putchar('\n');

    printf("BFS traverse: ");
    BFSTraverse(&al);
    putchar('\n');

    printf("The degree of each vertex: ");
    int i = 0;
    for(i = 0;i < al.vexnum;i ++)
    {
        printf("%d: ",al.vlist[i].date);
        printf("%d",FindOutDegree(&al,al.vlist[i].date)+
        			FindInDegree(&al,al.vlist[i].date));
        if(i != al.vexnum-1) printf(", ");
    }
    return 0;
}
//测试数据
/*
3 8 9
1 2 3 4 5 6 7 8
1 2
1 3
2 4
2 5
4 8
5 8
3 6
3 7
6 7

*/
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值