作者的话
大底包含了数据结构寒假硬性规定的作业代码,并非最优解,仅供参考。勿要无脑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;
}