NEFU数据结构作业答案大礼包(三)

作者的话

大底包含了数据结构寒假硬性规定的作业代码,并非最优解,仅供参考。勿要无脑copy,对自己负责。如果代码有误或者优化建议,直接相应博客下方评论或者qq找我。如果对代码有理解不了的或者疑惑可以询问我,但是请确保你已经自己思考过或者查过搜索引擎(如果我原模原样搜到了资料的话我会锤你的hh)。一些语法和库的资料查询网站受个人风格影响,部分题目解题方式可能没按照教学要求,如有必要请自己按教学要求做一遍。如果可以的话,麻烦借鉴完以后给我博客来个三连啥的,这可能对我以后找工作或者其他博客的推广什么的有些帮助,感谢
 

一、寒假作业3-图

 笔者认为邻接表过于繁琐,故采取邻接矩阵解题

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

int mp[100][100];
int visit[100];
void dfs(int x,int n)
{
   int i;
   visit[x]=1;
   for(i=1;i<=n;i++)
   {
       if(!visit[i]&&mp[x][i])
       {
          dfs(i,n);
       }
   }
}
int main()
{
    int T,n,m,u,v,i,count,tmp;
      count=0;
       scanf("%d%d",&n,&m);
       memset(mp,0,sizeof(mp));
       memset(visit,0,sizeof(visit));

     ​    ​for(i=0;i<=n-1;i++)
       {
           scanf("%d",&tmp);

       }//点的符号没啥用
    ​    ​for(i=0;i<=m-1;i++)
       {
           scanf("%d%d",&u,&v);
           mp[u][v]=mp[v][u]=1;
       }
       for(i=1;i<=n;i++)
       {
           if(!visit[i])
           {
              dfs(i,n);
              count++;
           }
       }
       printf("%d\n",count);
    return 0;
}

这当然不是我邻接表做法一直不给通过啦(咬牙切齿),以下我给出我的邻接表解法,如有兴趣可联系笔者一起讨论

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

#define MAXSIZE 100
using namespace std;

typedef struct ArcNode { //边点集
    int adjvex;     //弧头,该边另一条结点位置
    int weight;     //边的权重
    struct ArcNode* next;   //弧尾?指向下一条边的指针
}ArcNode;

typedef struct VNode {   //点集
    char data;  //顶点信息
    ArcNode* first; //与这个点相连的所有边点
}VNode, AdjList[MAXSIZE];

typedef struct {
    AdjList vertices;   //存放顶点信息的数组
    int vexnum, arcnum;//当前顶点数和边数
}Graph;

int LocateVex(Graph G, int v) {
    for (int i = 1; i < G.vexnum; i++) {
        if (G.vertices[i].data == v)
            return i;
    }
}
void CreateUDG(Graph& G) {
    scanf("%d%d", &G.vexnum, &G.arcnum);
    for (int i = 1; i <= G.vexnum; i++) {
        scanf("%d", &G.vertices[i].data);
        G.vertices[i].first = NULL;
    }
    for (int i = 1; i <= G.arcnum; i++) {
        int n1, n2;
        int v1, v2;
        scanf("%d%d", &n1, &n2);
        v1 = LocateVex(G, n1);
        v2 = LocateVex(G, n2);
        ArcNode* p1 = new ArcNode;
        ArcNode* p2 = new ArcNode;
        p1->adjvex = v2;
        p1->next = G.vertices[v1].first;
        G.vertices[v1].first = p1;
        //无序表则加入p2参数
        p2->adjvex=v1;
        p2->next=G.vertices[v2].first;
        G.vertices[v2].first = p2;
    }
}
//深度优先遍历
int visited[100];
void DFS(Graph G, int i) {
    ArcNode *p;
    visited[i] = 1;
    p = G.vertices[i].first;
    while(p){
        if(!visited[p->adjvex])
        DFS(G, p->adjvex);
        p = p->next;
        }
}

//求连通分量
int getNum(Graph G) {
    int i, count = 0; //记录连通分量个数
    for(i = 0; i < G.vexnum; i++)
        visited[i] = 0;
    for(i = 0; i < G.vexnum; i++)
        if(!visited[i]){
            count++;
            DFS(G, i);
        }
    return count;
}


int main()
{
    Graph G;
    CreateUDG(G);
    //TopSort(G);
    printf("%d",getNum(G));
    return 0;
}

思路如图有n个顶点,且有n-1条边,一次遍历即可访问所以点,此图就是树 

这道题依旧两个解法,必须整!!!

解法一邻接矩阵

#include<stdio.h>
#include<stdlib.h>
#define N 100
typedef int ElemType;
int n;
int a[N][N],vis[N],cnt;
void dfs(int pos){	
	vis[pos]=1;
	cnt++;
	int i;
	for(i=1;i<=n;i++){
		if(a[pos][i]&&vis[i]==0){
			dfs(i);
		}
	}
}
int main()
{
	int i,j,m,tmp;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
        scanf("%d",&tmp);
	for(i=1;i<=m;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		a[x][y]=a[y][x]=1;
	}
	dfs(1);
	if(m==n-1&&cnt==n){
		puts("1");
	}
	else{
		puts("0");
	}
	return 0;
}

解法二:邻接表,依旧存在问题无法通过(咬牙切齿)

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

#define MAXSIZE 100
using namespace std;

typedef struct ArcNode { //边点集
    int adjvex;     //弧头,该边另一条结点位置
    int weight;     //边的权重
    struct ArcNode* next;   //弧尾?指向下一条边的指针
}ArcNode;

typedef struct VNode {   //点集
    char data;  //顶点信息
    ArcNode* first; //与这个点相连的所有边点
}VNode, AdjList[MAXSIZE];

typedef struct {
    AdjList vertices;   //存放顶点信息的数组
    int vexnum, arcnum;//当前顶点数和边数
}Graph;

int LocateVex(Graph G, int v) {
    for (int i = 1; i < G.vexnum; i++) {
        if (G.vertices[i].data == v)
            return i;
    }
}
void CreateUDG(Graph& G) {
    scanf("%d%d", &G.vexnum, &G.arcnum);
    for (int i = 1; i <= G.vexnum; i++) {
        scanf("%d", &G.vertices[i].data);
        G.vertices[i].first = NULL;
    }
    for (int i = 1; i <= G.arcnum; i++) {
        int n1, n2;
        int v1, v2;
        scanf("%d%d", &n1, &n2);
        v1 = LocateVex(G, n1);
        v2 = LocateVex(G, n2);
        ArcNode* p1 = new ArcNode;
        ArcNode* p2 = new ArcNode;
        p1->adjvex = v2;
        p1->next = G.vertices[v1].first;
        G.vertices[v1].first = p1;
        //无序表则加入p2参数
        p2->adjvex=v1;
        p2->next=G.vertices[v2].first;
        G.vertices[v2].first = p2;
    }
}
//深度优先遍历
int visited[100];
void DFS(Graph G, int i) {
    ArcNode *p;
    visited[i] = 1;
    p = G.vertices[i].first;
    while(p){
        if(!visited[p->adjvex])
        DFS(G, p->adjvex);
        p = p->next;
        }
}

//求连通分量
int getNum(Graph G) {
    int i, count = 0; //记录连通分量个数
    for(i = 0; i < G.vexnum; i++)
        visited[i] = 0;
    for(i = 0; i < G.vexnum; i++)
        if(!visited[i]){
            count++;
            DFS(G, i);
        }
    return count;
}

int visit[100];
void DFS2(Graph* G, int v, int& vn, int& en)
{
	ArcNode* p;
	visit[v] = 1;
	++vn;				//顶点访问自增,记录顶点个数
	p = G->vertices[v].first;
	while (p != NULL)
	{
		++en;		//边数自增
		if (visit[p->adjvex == 0])
			DFS2(G, p->adjvex, vn, en);
		p = p->next;
	}
}
int GisTree(Graph* G)
{
	int vn = 0, en = 0, i;		//vn为顶点个数,en为边数
	for (i = 0; i < G->vexnum; ++i)
		visit[i] = 0;
	DFS2(G, 1, vn, en);	//	判断连通图条件,其中en/2是因为访问新节点时,边数恰好时实际的两倍
	if (vn == G->vexnum && en / 2 == G->vexnum - 1)
		return 1;
	else
		return 0;
}

int main()
{
    Graph G;
    CreateUDG(G);
    //TopSort(G);
    printf("%d",getNum(G));
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烟雨平生9527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值