图邻接矩阵 邻接表的建立c _数据结构课程设计

图邻接矩阵 邻接表的建立c  _数据结构课程设计
图邻接矩阵 邻接表的建立c  _数据结构课程设计

一.需求分析

1.运行环境

硬件:计算机486/64M以上

操作系统: WIN9x 以上/WIN2000/WIN XP/WIN ME

相关软件:vistualC++

2.程序所实现的功能:

(1)建立并显示图的邻接表。

(2)深度优先遍历,显示遍历结果。

(3)对该图进行拓扑排序,显示排序结果。

(4)给出某一确定顶点到所有其它顶点的最短路径。

3.程序的输入,包含输入的数据格式和说明

(1)输入顶点数,及各顶点信息(数据格式为整形)

(2)输入边数,及权值(数据格式为整形)

4.程序的输出,程序输出的形式

(1)输出图的邻接表、深度优先遍历结果、拓扑排序结果。

(2)输入某一确定顶点到其它所有顶点的最短路径。

5.测试数据

二、设计说明

1、算法设计的思想

建立图类,建立相关成员函数。最后在主函数中实现。具体成员函数的实现请参看源程序。

2、主要的数据结构设计说明

图邻接矩阵、邻接表的建立。图的深度优先遍历、拓扑排序、顶点之间的最短路径。

3、程序的主要模板template class Graph

4、程序的主要函数

Graph、link()、DFTraverse()、TopologicalOrder()、

TopologicalOrder()、GetVertexPos()、ShortestPath

三、上机结果及体会

1、实际完成的情况说明

主要程序参考教材《数据结构——C++版》。

2、程序的性能分析

可连续建图

3、上机过程中出现的问题及其解决方案。

编译没有错误,但结果有问题。解决方案:虽然程序的编译通过,只能说明语法上没有问题,结果只所以不正确是因为算法上原因。

4、程序中可以改进的地方说明

程序中的深度优先遍历,浪费空间较大,可以考虑用循环来做。但这样将付出代码长度度加长的代价。

5、程序中可以扩充的功能及设计实现假想

实现假想:随用户的输入可以随时动态的显示图的生成。

6、收获及体会

编写程序即是一件艰苦的工作,又是一件愉快的事情。最大的收获:编程时如果遇到看似简单但又无法解决的问题,很容易灰心丧气。此时切不可烦躁,一定要冷静的思考,认真的分析。要勇敢的面对问题,勇敢的接受问题,勇敢的处理问题,最后最勇敢的解决问题。

四、参考文献

数据结构(C++版)叶核亚主编机械工业出版社

数据结构经典算法实现与习题解答汪杰编著人民邮电出版社

数据结构课程设计苏仕华编著机械工业出版社

数据结构程序设计题典李春葆编著清华大学出版社

数据结构课程与题解(用C/C++描述)胡圣荣编著北京大学出版社

[程序运行流程图]

char op //程序控制变量

If(op=='Y'||op=='y') if(op=='N'||op=='n')

//本程序是邻接矩阵,邻接表的利用,共有4项功能,分别是:

//(1)建立并显示图的邻接表。

//(2)以非递归方式进行深度优先遍历,显示遍历结果。

//(3)对该图进行拓扑排序,显示排序结果。

//(4)给出某一确定顶点到所有其它顶点的最短路径。

#include

using namespace std;

const int MaxVertexes=20; //最大的顶点数

const int b=10000;

template class Graph ;

struct ArcNode{//定义边结点

friend class Graph ;

int adjvex; //和边(或弧)相关联的另一个顶点序号

int weight; //边(或弧)上的信息

ArcNode *nextarc ; //指向下一条边结点的指针

ArcNode(int v,int w ) : adjvex( v ),weight(w),nextarc( NULL ){ }

};//构造函数

template

struct VertexNode{// 定义顶点结点

friend class Graph ;

Type data; //顶点的信息

ArcNode *firstarc ; //指向依附该顶点的边链表

};

template class Graph

{

VertexNode * VTable; //顶点表

int CurrentNumVertexes; //当前的顶点数

int CurrentNumArcs; //当前的边(或弧)数

public:

int GetVertexPos( const Type &v );// 取顶点v在数组中的位置

Graph(Type v[],int num=MaxVertexes); //构造函数

Type GetValue(int v); //取图中顶点v的值,如果顶点v不存在则返回空 int Getweight(int v1,int v2); //取边(或弧)上的权值

int GetFirstNeighbor(int v); //取图中顶点v的第一个邻接点的序号。如果不存在返回-1

int GetNextNeighbor(int v1, int v2); //取图中下一个邻接点

int Arcs[MaxVertexes][MaxVertexes];//用数组记录每个边的信息

int InVertex(Type &v); //在图中插入结点

int InsertArc(int v1, int v2,int w);//在图中插入依附于v1和v2的边或弧,w是信息

int NumberOfVertexes( ){return CurrentNumVertexes; } //返回当前的顶点数

int NumberOfArcs(){ return CurrentNumArcs; } //返回当前的边(或弧)数

int *dist; //最短路径长度数组

int *InDegree; //入度数组,记录每个顶点的入度

int *path; //最短路径的数组

int *s; //最短路径终点数组

void link(); //输出邻接链表

void DFS(const int v,int visited[]);//深度优先搜索

void DFTraverse (); //深度遍历

void TopologicalOrder(); //拓扑排序

void ShortestPath(int n,int v);//最短路径

};

//////////////////////////////////////////////////////////////////////////////// ///

templateint Graph::

GetVertexPos(const Type &v ){ //根据顶点v查找该顶点在邻接表中的位置

for(int i=0;i

if(VTable[i].data==v) return i;

return -1;

}

templateGraph::Graph( Type v[] , int num=MaxVertexes) : CurrentNumVertexes(0), CurrentNumArcs(0)

{

Type tail, head;

int i=0,e,h,t,w,p=0;

while(p

for(int j=0;j

Arcs[p][j]=b;

if(p==j) {Arcs[p][j]=0;}

}

p++;

}

InDegree=new int[MaxVertexes];

VTable=new VertexNode[MaxVertexes];//创建顶点表

for(i=0;i

{ InVertex(v[i]); //在顶点表中插入顶点v[i]

InDegree[i]=0;

}

cout<<"输入边的条数:"; cin >> e;//输入边的条数

cout<

for(i=0;i< e;i++){ //逐条输入边

cout<<"输入第"<

cin>>tail>>head>>w; //输入一条边

int j=GetVertexPos(head);

while((t=GetVertexPos(tail))==-1)

cout<<"输入的顶点(tail)不存在";

while((h = GetVertexPos(head ))==-1)

cout<<"输入的顶点(head)不存在";

InsertArc (t,h,w); //插入一条边

InDegree[j]++; //顶点j的入度加1

cout<

}

}

templateType Graph::

GetValue(int v){ //取图中顶点v的值,如果顶点v不存在,则返回空 if(v>=0&&v

return NULL;

}

templateint Graph::

Getweight(int v1,int v2)

{//取出以顶点v1和v2为两端点的边上的权值

if(v1>=0&&v1=0&&v2

ArcNode *p=VTable[v1].firstarc;

while(p!=NULL){

if(p->adjvex==v2) {return p->weight;}

else {p=p->nextarc; }

}

} return NULL;

}

templateint Graph::

GetFirstNeighbor(int v){//查找顶点v的第一个邻接顶点的位置

if(v>=0&&v

ArcNode *p=VTable[v].firstarc;

if(p!=NULL) return p->adjvex;

}

return -1;

}

templateint Graph::

GetNextNeighbor(int v1,int v2){//查找顶点v1的在v2之后的下一个邻接顶点,如果不存在返回-1

if (v1!=-1){

ArcNode *p=VTable[v1].firstarc;

while(p!=NULL){

if(p->adjvex==v2&&p->nextarc!=NULL)

return p->nextarc->adjvex;//返回下一个邻接顶点在邻接表中的位置

else p=p->nextarc;

}

}

return -1;//没有查到下一个邻接顶点返回-1

}

templateint Graph::

InsertArc(int v1,int v2,int w)

{//在图中插入弧

if(v1>=0&&v1

Arcs[v1][v2]=w;

ArcNode *newnode =new ArcNode(v2,w);

ArcNode *h=VTable[v1].firstarc;

if(h!=NULL){

ArcNode *p=h;

while(h!=NULL&&h->adjvex

p=h; h=h->nextarc;

}

newnode->nextarc=p->nextarc;

p->nextarc=newnode;

return 1;

}

VTable[v1].firstarc=newnode;

return 1;

}

return -1;

}

templateint Graph::

InVertex(Type &v)

{//在图中插入顶点,插入成功则返回1,否则返回0

if(CurrentNumVertexes

VTable[CurrentNumVertexes].data=v;

VTable[CurrentNumVertexes].firstarc=NULL;

CurrentNumVertexes++; return 1;

}

return -1;

}

/////////////////////////////////////////////////////////////////////// //以下是实验要求的函数

//输出邻接表

templatevoid Graph::link(){

cout<<"输出邻接表:"<

for(int i=0;i

cout<

int a=GetFirstNeighbor(i);

if(a!=-1) cout<<"->"<

for(int j=a;j!=-1;j=a){

a=GetNextNeighbor(i,j);

if(a!=-1) cout<<"->"<

}

cout<

}

}

//拓扑排序

templatevoid Graph::

TopologicalOrder()

{

int m=0;//m为输出的顶点数,初始值为0

for(int i=0;i

for(int n=0;n

if(InDegree[n]==0){

m++;//输出的顶点数加1

cout<

InDegree[n]=-1;

for(int t=0;t

if(n>=0&&n

if(t>=0&&t

if(Arcs[n][t]!=0&&Arcs[n][t]!=b)

InDegree[t]--;

}

}

}

for(int h=0;h

cout<

} cout<

}

}

}

if(m

//深度遍历

template

void Graph::

DFS(const int v,int visited[ ])

{

cout<< VTable[v].data<<" "; //访问顶点 v

visited[v] =1; //顶点v 作访问标记

int w = GetFirstNeighbor (v);

while (w != -1) { //若顶点 w 存在

if (!visited[w]) DFS (w,visited);

w = GetNextNeighbor(v,w);

} //重复检测 v 的所有邻接顶点

}

template

void Graph ::

DFTraverse ()

{

int i, n = NumberOfVertexes() ; //取图的顶点个数

int * visited = new int [n]; //定义访问标记数组 visited

for ( i = 0; i < n; i++ )

visited [i] = 0; //访问标记数组 visited 初始化

for ( i = 0; i < n; i++ ) //对图中的每一个顶点进行判断

if (!visited [i]) DFS (i, visited );

delete[ ]visited; //释放 visited

}

//求最短路径

templatevoid Graph::

ShortestPath(int n,int v)

{

int min,u;

dist=new int[n]; s=new int[n]; path=new int[n];

for(int j=0;j

dist[j]=Arcs[v][j]; s[j]=0;

if(j!=v&&dist[j]

else path[j]=-1; s[v]=1;

}

for(int i=0;i<=n-1;i++){

min=MaxVertexes; u=v;

for(int j=0;j

if(!s[j]&&dist[j]

u=j; min=dist[j];

}

s[u]=1;

for(int w=0;w

if(!s[w]&&dist[u]+Arcs[u][w]

{

dist[w]=dist[u]+Arcs[u][w];

path[w]=u;

}

if(v!=i&&dist[i]!=10000&&v!=path[i])

cout<

else if(v!=i&&dist[i]!=10000)

cout<

}

for(int m=0;m

cout<

}

//主函数

void main(){

char op;

do{

int m,i=0,j=0,w;

char a[20],c;

cout<<"请你输入顶点的个数:"; cin>>m;

for(i=0;i

cout<<"请输入第"<

cin>>a[i]; cout<

}

GraphG(a,m);

G.link();

cout<<"深度遍历:"<

G.DFTraverse();

cout<

cout<<"拓扑排序:"<

G.TopologicalOrder();

cout<

cout<<"输入最小路径的源头结点:"<

cin>>c;

w=G.GetVertexPos(c);

G.ShortestPath(m,w);

loop:cout<<"是继续?(Y or N)"<

cin>>op;

if(op=='N'||op=='n')break;

if(op!='Y'&&op!='y'&&op!='N'&&op!='n')goto loop; }while(op=='Y'||op=='y');

}

图的邻接矩阵和邻接表相互转换

图的邻接矩阵和邻接表相互转换 图的邻接矩阵存储方法具有如下几个特征:1)无向图的邻接矩阵一定是一个对称矩阵。 2)对于无向图的邻接矩阵的第i 行非零元素的个数正好是第i 个顶点的度()i v TD 。3)对于有向图,邻接矩阵的第i 行非零元素的个数正好是第i 个顶点的出度()i v OD (或入度 ()i v ID ) 。4)用邻接矩阵方法存储图,很容易确定图中任意两个顶点之间是否有边相连;但是,要确定图中有多少条边,则必须按行、按列对每个元素进行检测,所发费得时间代价大。 邻接表是图的一种顺序存储与链式存储相结合的存储方法。若无向图中有n 个顶点、e 条边,则它的邻接表需n 个头结点和2e 个表结点。显然,在边稀疏的情况下,用邻接表表示图比邻接矩阵存储空间。在无向图的邻接表中,顶点i v 的度恰好是第i 个链表中的结点数,而在有向图中,第i 个链表中结点个数是顶点i v 的出度。 在建立邻接表或邻逆接表时,若输入的顶点信息即为顶点的编号,则建立临接表的时间复杂度是)(e n O +;否则,需要通过查找才能得到顶点在图中位置,则时间复杂度为)*(e n O 。在邻接表上容易找到任意一顶点的第一个邻接点和下一个邻接点,但要判断任意两个顶点之间是否有边或弧,则需要搜索第i 个或第j 个链表,因此,不及邻接矩阵方便。 邻接矩阵和邻接表相互转换程序代码如下: #include #define MAX 20 //图的邻接表存储表示 typedef struct ArcNode{ int adjvex; //弧的邻接定点 char info; //邻接点值 struct ArcNode *nextarc; //指向下一条弧的指针 }ArcNode; typedef struct Vnode{ //节点信息 char data; ArcNode *link; }Vnode,AdjList[MAX]; typedef struct{ AdjList vertices; int vexnum; //节点数 int arcnum; //边数

图的邻接矩阵存储结构建立汇总

课程名称: 《数据结构》课程设计课程设计题目:图的邻接矩阵存储结构建立 姓名:XXX 院系:计算机学院 专业:计算机科学技术 年级:11级 学号:XXXXXXXX 指导教师:XXX 2013年9月28日

目录 1 课程设计的目的 (3) 2需求分析 (3) 3 课程设计报告内容 (3) 3.1 概要设计 (3) 3.2 详细设计 (4) 3.3 调试分析 (5) 3.4 用户手册 (5) 3.5 程序清单 (5) 3.6 测试结果 (10) 4 小结 (12) 5 参考文献 (12)

1.课程设计的目的 (1) 熟练使用 C 语言编写程序,解决实际问题; (2) 了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力; (3) 初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能; (4) 提高综合运用所学的理论知识和方法独立分析和解决问题的能力; 2.需求分析 问题描述:建立图的邻接矩阵存储结构(图的类型可以是有向图或有向网、无向图或无向网,学生可以任选一种类型),能够输入图的顶点和边的信息,并存储到相应存储结构中,而后给出图的DFS,BFS次序。 要求: ①先任意创建一个图; ②图的DFS,BFS的递归和非递归算法的实现。 3.课程设计报告内容 3.1概要设计 1.函数 ①主函数:main( ) ②创建无向图:CreateGraph( )

③深度优先遍历图:DFS( ) ④广度优先遍历图:BFS( ) 3.2详细设计 1.使用邻接矩阵作为图的存储结构,程序中主要用到的抽象数据类型: typedef struct { char vexs[MAX]; //顶点向量 int arcs[MAX][MAX]; //邻接矩阵 int vexnum,arcnum; //图的当前顶点数和弧数}Graph; 2.程序流程图:

数据结构课程设计

1.一元稀疏多项式计算器 [问题描述] 设计一个一元稀疏多项式简单计算器。 [基本要求] 输入并建立多项式; 输出多项式,输出形式为整数序列:n, c1, e1, c2, e2,……, cn, en ,其中n是多项式的项数,ci, ei分别是第i项的系数和指数,序列按指数降序排序; 多项式a和b相加,建立多项式a+b; 多项式a和b相减,建立多项式a-b; [测试数据] (2x+5x8-3.1x11)+(7-5x8+11x9)=(-3.1x11+11x9+2x+7) (6x-3-x+4.4x2-1.2x9)-(-6x-3+5.4x2-x2+7.8x15)=(-7.8x15-1.2x9-x+12x-3) (1+x+x2+x3+x4+x5)+(-x3-x4)=(x5+x2+x+1) (x+x3)+(-x-x3)=0 (x+x2+x3)+0=(x3+x2+x) [实现提示] 用带头结点的单链表存储多项式,多项式的项数存放在头结点中。 2.背包问题的求解 [问题描述] 假设有一个能装入总体积为T的背包和n件体积分别为w1, w2, …,wn的物品,能否从n件物品中挑选若干件恰好装满背包,即使w1+w2+…+wn=T,要求找出所有满足上述条件的解。例如:当T=10,各件物品的体积为{1,8,4,3,5,2}时,可找到下列4组解:(1,4,3,2)、(1,4,5)、(8,2)、(3,5,2) [实现提示] 可利用回溯法的设计思想来解决背包问题。首先,将物品排成一列,然后顺序选取物品转入背包,假设已选取了前i件物品之后背包还没有装满,则继续选取第i+1件物品,若该件物品“太大”不能装入,则弃之而继续选取下一件,直至背包装满为止。但如果在剩余的物品中找不到合适的物品以填满背包,则说明“刚刚”装入背包的那件物品“不合适”,应将它取出“弃之一边”,继续再从“它之后”的物品中选取,如此重复,直至求得满足条件的解,或者无解。 由于回溯求解的规则是“后进先出”因此自然要用到栈。 3.完全二叉树判断 用一个二叉链表存储的二叉树,判断其是否是完全二叉树。 4.最小生成树求解(1人) 任意创建一个图,利用克鲁斯卡尔算法,求出该图的最小生成树。 5.最小生成树求解(1人) 任意创建一个图,利用普里姆算法,求出该图的最小生成树。 6.树状显示二叉树 编写函数displaytree(二叉树的根指针,数据值宽度,屏幕的宽度)输出树的直观示意图。输出的二叉树是垂直打印的,同层的节点在同一行上。 [问题描述] 假设数据宽度datawidth=2,而屏幕宽度screenwidth为64=26,假设节点的输出位置用 (层号,须打印的空格数)来界定。 第0层:根在(0,32)处输出;

经典代码之图 邻接表转换成邻接矩阵

运行结果是: 请输入节点数和弧数:3 3 第1 个节点信息:5 第2 个节点信息:6 第3 个节点信息:7 第1 条弧的弧尾和弧头的位置:1 2 第2 条弧的弧尾和弧头的位置:2 3 第3 条弧的弧尾和弧头的位置:1 3 图的邻接表表示为: [1,5]-->[3,7]-->[2,6]-->^ [2,6]-->[3,7]-->[1,5]-->^ [3,7]-->[1,5]-->[2,6]-->^ 交换后是:: 图的邻接矩阵表示为: 0 1 1 1 0 1 1 1 0 请按任意键继续. . . 代码是: #include #include #define MAXV 100 typedef struct { int no; int info; }vertextype; typedef struct { int num; int edges[MAXV][MAXV]; // vertextype vexs[MAXV]; }mgraph; struct arcnode { int adjvex; int info;

struct arcnode *nextarc; }; struct vexnode { int data; struct arcnode *firstarc; }; struct graph { int vexnum,arcnum; vexnode vexpex[100]; }; struct graph *creatgraph() { int i,s,d; struct graph *g; struct arcnode *p,*q; g = (struct graph *)malloc(sizeof(struct graph)); printf("请输入节点数和弧数:"); scanf("%d%d", &g->vexnum, &g->arcnum); for(i=1; i<=g->vexnum; i++) { printf("第%d 个节点信息:",i); scanf("%d", &g->vexpex[i].data); g->vexpex[i].firstarc = NULL; } for(i=1; i<=g->arcnum; i++) { p = (struct arcnode *)malloc(sizeof(struct arcnode)); q = (struct arcnode *)malloc(sizeof(struct arcnode)); printf("第%d 条弧的弧尾和弧头的位置:",i); scanf("%d%d",&s,&d); p->adjvex = d; p->info = g->vexpex[d].data; p->nextarc = g->vexpex[s].firstarc; g->vexpex[s].firstarc = p; q->adjvex = s; q->info = g->vexpex[s].data; q->nextarc = g->vexpex[d].firstarc; g->vexpex[d].firstarc = q;

数据结构课程设计报告模板

课程设计说明书 课程名称:数据结构 专业:班级: 姓名:学号: 指导教师:成绩: 完成日期:年月日

任务书 题目:黑白棋系统 设计内容及要求: 1.课程设计任务内容 通过玩家与电脑双方的交替下棋,在一个8行8列的方格中,进行棋子的相互交替翻转。反复循环下棋,最后让双方的棋子填满整个方格。再根据循环遍历方格程序,判断玩家与电脑双方的棋子数。进行大小判断,最红给出胜负的一方。并根据y/n选项,判断是否要进行下一局的游戏。 2.课程设计要求 实现黑白两色棋子的对峙 开发环境:vc++6.0 实现目标: (1)熟悉的运用c语言程序编写代码。 (2)能够理清整个程序的运行过程并绘画流程图 (3)了解如何定义局部变量和整体变量; (4)学会上机调试程序,发现问题,并解决 (5)学习使用C++程序来了解游戏原理。 (6)学习用文档书写程序说明

摘要 本文的研究工作在于利用计算机模拟人脑进行下黑白棋,计算机下棋是人工智能领域中的一个研究热点,多年以来,随着计算机技术和人工智能技术的不断发展,计算机下棋的水平得到了长足的进步 该程序的最终胜负是由棋盘上岗双方的棋子的个数来判断的,多的一方为胜,少的一方为负。所以该程序主要运用的战术有削弱对手行动战术、四角优先战术、在游戏开局和中局时,程序采用削弱对手行动力战术,即尽量减少对手能够落子的位置;在游戏终局时则采用最大贪吃战术,即尽可能多的吃掉对手的棋子;而四角优先战术则是贯穿游戏的始终,棋盘的四角围稳定角,不会被对手吃掉,所以这里是兵家的必争之地,在阻止对手进角的同时,自己却又要努力的进角。 关键词:黑白棋;编程;设计

实现图的邻接矩阵和邻接表存储

实现图的邻接矩阵和邻接表存储 1.需求分析 对于下图所示的有向图G,编写一个程序完成如下功能: 1.建立G的邻接矩阵并输出之 2.由G的邻接矩阵产生邻接表并输出之 3.再由2的邻接表产生对应的邻接矩阵并输出之 2.系统设计 1.图的抽象数据类型定义: ADT Graph{ 数据对象V:V是具有相同特性的数据元素的集合,称为顶点集 数据关系R: R={VR} VR={|v,w∈V且P(v,w),表示从v到w的弧, 谓词P(v,w)定义了弧的意义或信息} 基本操作P: CreatGraph(&G,V,VR) 初始条件:V是图的顶点集,VR是图中弧的集合 操作结果:按V和VR的定义构造图G DestroyGraph(&G) 初始条件:图G存在 操作结果:销毁图G InsertVex(&G,v) 初始条件:图G存在,v和图中顶点有相同特征 操作结果:在图G中增添新顶点v …… InsertArc(&G,v,w) 初始条件:图G存在,v和w是G中两个顶点 操作结果:在G中增添弧,若G是无向的则还增添对称弧 …… DFSTraverse(G,Visit()) 初始条件:图G存在,Visit是顶点的应用函数 操作结果:对图进行深度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。

一旦Visit()失败,则操作失败 BFSTraverse(G,Visit()) 初始条件:图G存在,Visit是顶点的应用函数 操作结果:对图进行广度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。一旦Visit()失败,则操作失败 }ADT Graph 2.主程序的流程: 调用CreateMG函数创建邻接矩阵M; 调用PrintMatrix函数输出邻接矩阵M 调用CreateMGtoDN函数,由邻接矩阵M创建邻接表G 调用PrintDN函数输出邻接表G 调用CreateDNtoMG函数,由邻接表M创建邻接矩阵N 调用PrintMatrix函数输出邻接矩阵N 3.函数关系调用图: 3.调试分析 (1)在MGraph的定义中有枚举类型 typedef enum{DG,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网} 赋值语句G.kind(int)=M.kind(GraphKind);是正确的,而反过来M.kind=G.kind则是错误的,要加上那个强制转换M.kind=GraphKind(G.kind);枚举类型enum{DG,DN,UDG,UDN} 会自动赋值DG=0;DN=1,UDG=2,UDN=3;可以自动从GraphKind类型转换到int型,但不会自动从int型转换到GraphKind类型

数据结构与算法-图的邻接矩阵

实验报告实验日期:数据结构与算法课程: 图的邻接矩阵实验名称: 一、实验目的掌握图的邻接矩阵 二、实验内容必做部分 、给出图的邻接矩阵存储结构的类型定义。1 -1。v,返回其在vexs数组中的下标,否则返回2、实现LocateVex(G,v)操作函数:若找到顶点。、实现算法7.2(构造无向网)3&G) Status CreateUDN(MGraph 设计并实现无向网的输出算法,要求能显示顶点以及顶点之间的邻接关系(方式自定)4、 并进行输出。要求给出至少两组测试数据。在主函数中调用CreateUDN创建一个无向网,5、 选做部分 类型)编写下述操作函数:基于图的邻接矩阵存储结构(即MGraph若找不到这样返回该邻接点在顶点数组中的下标;1个邻接点,1、求下标为v的顶点的第-1。的邻接点,返回int FirstAdjVex(MGraph G,int v) 的顶点的下一个邻接点,返回该邻接点的下标;若w求下标为v的顶点相对于下标为2、找不到这样的邻接点,返回-1。 int NextAdjVex(MGraph G,int v,int w) 在主函数调用上述函数,给出测试结果。 三、实验步骤 必做部分 给出图的邻接矩阵存储结构的类型定义。、 1.

2、实现LocateVex(G,v)操作函数:若找到顶点v,返回其在vexs数组中的下标,否则返回-1。 3、实现算法7.2(构造无向网)。 &G) CreateUDN(MGraph Status

设计并实现无向网的输出算法,要求能显示顶点以及顶点之间的邻接关系(方式自定)、

4. 要求给出至少两组测试数据。并进行输出。、在主函数中调用CreateUDN创建一个无向网,5

图的邻接表存储方式.

图的邻接表存储方式——数组实现初探 焦作市外国语中学岳卫华在图论中,图的存储结构最常用的就是就是邻接表和邻接矩阵。一旦顶点的个数超过5000,邻接矩阵就会“爆掉”空间,那么就只能用邻接表来存储。比如noip09的第三题,如果想过掉全部数据,就必须用邻接表来存储。 但是,在平时的教学中,发现用动态的链表来实现邻接表实现时,跟踪调试很困难,一些学生于是就觉得邻接表的存储方式很困难。经过查找资料,发现,其实完全可以用静态的数组来实现邻接表。本文就是对这种方式进行探讨。 我们知道,邻接表是用一个一维数组来存储顶点,并由顶点来扩展和其相邻的边。具体表示如下图:

其相应的类型定义如下: type point=^node; node=record v:integer; //另一个顶点 next:point; //下一条边 end; var a:array[1..maxv]of point; 而用数组实现邻接表,则需要定义两个数组:一个是顶点数组,一个 是边集数组。

顶点编号结点相临边的总数s第一条邻接边next 此边的另一邻接点边权值下一个邻接边 对于上图来说,具体的邻接表就是: 由上图我们可以知道,和编号为1的顶点相邻的有3条边,第一条边在边集数组里的编号是5,而和编号为5同一个顶点的下条边的编号为3,再往下的边的编号是1,那么和顶点1相邻的3条边的编号分别就是5,3,1。同理和顶点3相邻的3条边的编号分别是11,8,4。如果理解数组表示邻接表的原理,那么实现就很容易了。 类型定义如下:

见图的代码和动态邻接表类似: 下面提供一道例题 邀请卡分发deliver.pas/c/cpp 【题目描述】

数据结构课程设计-图的邻接矩阵

数据结构 课程设计报告 设计题目:图的邻接矩阵存储结构 院系计算机学院 年级x 级 学生xxxx 学号xxxxxxxxxx 指导教师xxxxxxxxx 起止时间10-6/10-10 2013年10月10日

目录 1 需求分析 (4) 2 概要设计 (4) 2.1 ADT描述 (4) 2.2程序模块结构 (5) 2.3各功能模块 (6) 3详细设计 (7) 3.1类的定义 (7) 3.2 初始化 (8) 3.3 图的构建操作 (8) 3.4 输出操作 (9) 3.5 get操作 (9) 3.6 插入操作 (10) 3.7 删除操作 (100) 3.8 求顶点的度操作 (111) 3.9 深度遍历作 (11) 3.10 判断连通操作 (12) 3.11 主函数 (13) 4 调试分析 (16) 4.1调试问题 (16) 4.2 算法时间复杂度 (16) 5用户手册 (16) 5.1主界面 (16) 5.2 创建图 (17) 5.3插入节点 (17) 5.4 深度优先遍历 (17) 5.5 求各顶点的度 (18) 5.6 输出图 (18) 5.7 判断是否连通 (19) 5.8 求边的权值 (19) 5.9 插入边 (19) 5.10 删除边 (20) 结论 (20) 参考文献 (20)

摘要 随着计算机的普及,涉及计算机相关的科目也越来越普遍,其中数据结构是计算机专业重要的专业基础课程与核心课程之一,为适应我国计算机科学技术的发展和应用,学好数据结构非常必要,然而要掌握数据结构的知识非常难,所以对“数据结构”的课程设计比不可少。本说明书是对“无向图的邻接矩阵存储结构”课程设计的说明。 首先是对需求分析的简要阐述,说明系统要完成的任务和相应的分析,并给出测试数据。其次是概要设计,说明所有抽象数据类型的定义、主程序的流程以及各程序模块之间的层次关系,以及ADT描述。然后是详细设计,描述实现概要设计中定义的基本功操作和所有数据类型,以及函数的功能及代码实现。再次是对系统的调试分析说明,以及遇到的问题和解决问题的方法。然后是用户使用说明书的阐述,然后是测试的数据和结果的分析,最后是对本次课程设计的结论。 关键词:网络化;计算机;对策;图;储存。

数据结构课程设计报告

《数据结构课程设计》报告 题目:课程设计题目2教学计划编制 班级:700 学号:09070026 姓名:尹煜 完成日期:2011年11月7日

一.需求分析 本课设的任务是根据课程之间的先后的顺序,利用拓扑排序算法,设计出教学计划,在七个学期中合理安排所需修的所有课程。 (一)输入形式:文件 文件中存储课程信息,包括课程名称、课程属性、课程学分以及课程之间先修关系。 格式:第一行给出课程数量。大于等于0的整形,无上限。 之后每行按如下格式“高等数学公共基础必修6.0”将每门课程的具体信息存入文件。 课程基本信息存储完毕后,接着给出各门课程之间的关系,把每门课程看成顶点,则关系即为边。 先给出边的数量。大于等于0的整形。 默认课程编号从0开始依次增加。之后每行按如下格式“1 3”存储。此例即为编号为1的课程与编号为3的课程之间有一条边,而1为3的前驱,即修完1课程才能修3课程。 例: (二)输出形式:1.以图形方式显示有向无环图

2.以文本文件形式存储课程安排 (三)课设的功能 1.根据文本文件中存储的课程信息(课程名称、课程属性、课程学分、课程之间关系) 以图形方式输出课程的有向无环图。 拓展:其显示的有向无环图可进行拖拽、拉伸、修改课程名称等操作。 2.对课程进行拓扑排序。 3.根据拓扑排序结果以及课程的学分安排七个学期的课程。 4.安排好的教学计划可以按图形方式显示也可存储在文本文件里供用户查看。 5.点击信息菜单项可显示本人的学好及姓名“09070026 尹煜” (四)测试数据(见六测设结果)

二.概要设计 数据类型的定义: 1.Class Graph即图类采用邻接矩阵的存储结构。类中定义两个二维数组int[][] matrix 和Object[][] adjMat。第一个用来标记两个顶点之间是否有边,为画图服务。第二个 是为了实现核心算法拓扑排序。 2.ArrayList list用来存储课程信息。DrawInfo类是一个辅助画图的类,其中 包括成员变量num、name、shuxing、xuefen分别代表课程的编号、名称、属性、 学分。ArrayList是一个DrawInfo类型的数组,主要用来在ReadFile、DrawG、DrawC、SaveFile、Window这些类之间辅助参数传递,传递课程信息。 3.Class DrawInfo, 包括int num;String name;String shuxing;float xuefen;四个成员变量。 4.Class Edge包括int from;int to;double weight;三个成员变量。 5.Class Vertex包括int value一个成员变量。 主要程序的流程图: //ReadFile.java

用邻接矩阵表示法创建有向图(数据结构)

#include #include #include #define MAX_VERTEX_NUM 20 //定义最多顶点个数 #define INFINITY32768 //定义无穷大 //描述图的类型,用枚举型类型来说明 typedef enum{DG,DN,UDG,UDN}GraphKind; //定义顶点数据类型 typedef char V ertexData; //定义邻接矩阵中元素值(即边信息)的数据类型 typedef int ArcNode; //定义图的邻接矩阵类型:一个顶点信息的一维数组,一个邻接矩阵、当前图中包含的顶点数、边数以及图类型(有向图、有向网、无向图、无向网) typedef struct { V ertexData vertex[MAX_VERTEX_NUM]; ArcNode arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; int vertexnum,arcnum; GraphKind kind; } AdjMatrix;//图的邻接矩阵表示类型 int LocateV ertex(AdjMatrix *G,V ertexData v) //求顶点位置函数 { int j=-1,k; for(k=0;kvertexnum;k++) { if(G->vertex[k]==v) { return k; } } return j; } int CreateDN(AdjMatrix *G) //创建一个又向网 { int i,j,k,weight; V ertexData v1,v2; printf("输入图的顶点数和弧数,以逗号分隔\n"); //输入图的顶点数和弧数 scanf("%d,%d",&G->vertexnum,&G->arcnum); for(i=0;ivertexnum;i++) //初始化邻接矩阵(主对角线元素全为零,其余元素为无穷大) {

数据结构课程设计

《数据结构》 课程设计报告 学号 姓名 班级 指导教师 安徽工业大学计算机学院 2010年6月

建立二叉树和线索二叉树 1.问题描述: 分别用以下方法建立二叉树并用图形显示出来: 1)用先序遍历的输入序列 2)用层次遍历的输入序列 3)用先序和中序遍历的结果 2.设计思路: 分三个方式去实现这个程序的功能,第一个实现先序遍历的输入数列建立二叉树;第二个是用层次遍历的方法输入序列;第三个是用先序和后序遍历的结果来建立二叉树;三种方法建立二叉树后都进行输出。关键是将这三个实现功能的函数写出来就行了;最后对所建立的二叉树进行中序线索化,并对此线索树进行中序遍历(不使用栈)。 3.数据结构设计: 该程序的主要目的就是建立二叉树和线索二叉树,所以采用树的存储方式更能完成这个程序; 结点的结构如下: typedef struct bnode { DataType data; int ltag,rtag; struct bnode *lchild, *rchild; } Bnode, *BTree; 4.功能函数设计: BTree CreateBinTree() 用先序遍历的方法讲二叉树建立; BTree CREATREE() 用队列实现层次二叉树的创建; void CreatBT(); 用先序和中序遍历的结果建立二叉树; void InThread(BTree t,BTree pre) 中序线索化; 5.编码实现: #include #include #define max 100 typedef struct bnode { char data; int ltag,rtag; struct bnode *lchild,*rchild; }Bnode,*BTree; BTree Q[max]; BTree CREATREE() { char ch; int front=1,rear=0;

数据结构课程设计

一、高校社团管理 在高校中,为了丰富学生的业余生活,在学校的帮助下,会成立许多社团,少则几个,多则几十个。为了有效管理这些社团,要求编写程序实现以下功能:1.社团招收新成员; 2.修改社团相应信息 3.老成员离开社团 4.查询社团情况; 5.统计社团成员数; 二、简单文本编辑器 设计一个文本编辑器,允许将文件读到内存中,也就是存储在一个缓冲区中。这个缓冲区将作为一个类的内嵌对象实现。缓冲区中的每行文本是一个字符串,将每行存储在一个双向链表的结点中,要求设计在缓冲区中的行上执行操作和在单个行中的字符上执行字符串操作的编辑命令。 基本要求: 包含如下命令列。可用大写或小写字母输入。 R:读取文本文件到缓冲区中,缓冲区中以前的任何内容将丢失,当前行是文件的第一行; W:将缓冲区的内容写入文本文件,当前行或缓冲区均不改变。 I:插入单个新行,用户必须在恰当的提示符的响应中键入新行并提供其行号。 D:删除当前行并移到下一行; F:可以从第1行开始或从当前行开始,查找包含有用户请求的目标串的第一行; C:将用户请求的字符串修改成用户请求的替换文本,可选择是仅在当前行中有效的还是对全文有效的。 Q:退出编辑器,立即结束; H:显示解释所有命令的帮助消息,程序也接受?作为H的替代者。 N:当前行移到下一行,也就是移到缓冲区的下一行; P:当前行移到上一行,也就是移到缓冲区的上一行;

B:当前行移到开始处,也就是移到缓冲区的第一行; E:当前行移到结束处,也就是移到缓冲区的最后一行; G:当前行移到缓冲区中用户指定的行; V:查看缓冲区的全部内容,打印到终端上。 三、电话客户服务模拟 一个模拟时钟提供接听电话服务的时间(以分钟计),然后这个时钟将循环的 自增1(分钟)直到达到指定时间为止。在时钟的每个"时刻",就会执行一次检查来看看对当前电话服务是否已经完成了,如果是,这个电话从电话队列中删除,模 拟服务将从队列中取出下一个电话(如果有的话)继续开始。同时还需要执行一个检查来判断是否有一个新的电话到达。如果是,其到达时间被记录下来,并为其产生一个随机服务时间,这个服务时间也被记录下来,然后这个电话被放入电话队列中,当客户人员空闲时,按照先来先服务的方式处理这个队列。当时钟到达指定时间时,不会再接听新电话,但是服务将继续,直到队列中所偶电话都得到处理为止。 基本要求: (1)程序需要的初始数据包括:客户服务人员的人数,时间限制,电话的到达速率,平均服务时间 (2)程序产生的结果包括:处理的电话数,每个电话的平均等待时间 四、停车场管理 设停车场是一个可停放n辆车的狭长通道,且只有一个大门可供汽车进出。在停车场内,汽车按到达的先后次序,由北向南依次排列(假设大门在最南端)。若停车场内已停满n辆车,则后来的汽车需在门外的便道上等候,当有车开走时,便道上的第一辆车即可开入。当停车场内某辆车要离开时,在它之后进入的车辆必须先退出停车场为它让路,待该辆车开出大门后,其他车辆再按原次序返回车场。每辆车离开停车场时,应按其停留时间的交费(从进入便道开始计时)。在这里假设汽车从便道上开走时不收取任何费用 基本要求: (1)汽车的输入信息格式为(到达/离去的标识,汽车牌照号码,到达/离去的时间)

图采用邻接矩阵存储结构

图采用邻接矩阵存储结构 #define TRUE 1 #define FALSE 0 #define MAXV 20 typedef int V ertexType; //用顶点编号表示顶点 typedef struct { // 图的定义 int edges[MAXV][MAXV] ; // 边数组 int n, e; //顶点数,弧数 V ertexType vexs[MAXV]; // 顶点信息 } MGraph; 1、创建具有n个顶点e条边的无向图 void CreateUDG(MGraph &G,int n,int e) { int i,j,u,v; G.n=n;G.e=e; /* printf("请输入%d个顶点的编号:\n",n); for(i=0;i

void CreateDG(MGraph &G,int n,int e) { int i,j,u,v; G.n=n;G.e=e; /* printf("请输入%d个顶点的编号:\n",n); for(i=0;i

邻接矩阵创建有向网的实现

韩山师范学院 实验题目: 邻接矩阵创建有向网算法实现 班级:2015级软工班作者:黄俊聪 #include using namespace std; #define MaxInt 32767 //表示极大值,即∞ #define MVNum 100 //最大顶点数 #define OK 1 #define ERROR 0; typedef char VerTexType;//假设顶点的数据类型为字符型 typedefintArcType;//假设边的权值类型为整型 typedefint Status; typedefstruct { VerTexTypevexs[MVNum];//顶点表 ArcType arcs[MVNum][MVNum];//邻接矩阵 intvexnum,arcnum;//图的当前点数和边数 }AMGraph; Status LocateVex(AMGraphG,char v) {

for(i=0; i>G.vexnum>>G.arcnum;//输入总定点数,总边数 cout<<"次输入点的信息:"<>G.vexs[i]; for(int i=0;i>v1>>v2>>w;//输入一条边依附的顶点及权值 i=LocateVex(G,v1); j=LocateVex(G,v2);//确定v1和v2在G中的位置,即顶点数组的下表 G.arcs[i][j]=w;//边的权值置为w } return OK; } void PrintMatrix(AMGraph&G)//输出邻接矩阵 { inti,j; printf("邻接矩阵为:\n"); for(i=0;i

数据结构课程设计报告

数据结构课程设计报告 题目:5 班级:计算机1102 学号:4111110030 姓名:陈越 指导老师:王新胜

一:需求分析 1.运行环境 TC 2.程序所需实现的功能 几种排序算法的演示,要求给出从初始开始时的每一趟的变化情况,并对各种排序算法性能作分析和比较: (1)直接插入排序; (2)折半插入排序; (3)冒泡排序; (4)简单选择排序; (5)快速排序; (6)堆排序; (7)归并排序. 二:设计说明 1.算法设计的思想 1)、直接插入排序 排序过程:整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序。 2)、折半插入排序 排序过程:用折半查找方法确定插入位置的排序叫折半插入排序。 3)、冒泡排序

排序过程:将第一个记录的关键字与第二个记录的关键字进行比较,若为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与第三个记录;依次类推,直至第n-1个记录和第n个记录比较为止——第一趟冒泡排序,结果关键字最大的记录被安置在最后一个记录上。对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的记录被安置在第n-1个记录位置。重复上述过程,直到“在一趟排序过程中没有进行过交换记录的操作”为止 4)、简单选择排序 排序过程:首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换。再通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录,将它与第二个记录交换。重复上述操作,共进行n-1趟排序后,排序结束。 5)、快速排序 基本思想:通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录进行排序,以达到整个序列有序。 排序过程:对r[s……t]中记录进行一趟快速排序,附设两个指针i和j,设枢轴记录rp=r[s],x=rp.key。初始时令i=s,j=t。首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp交换。再从i所指位置起向后搜索,找到第一个关键字大于x的记录,和rp交换。重复上述两步,直至i==j为止。再分别对两个子序列进行快速排序,直到每个子序列只含有一个记录为止。 6)、堆排序 排序过程:将无序序列建成一个堆,得到关键字最小(或最大)的记录;输

邻接矩阵表示图深度广度优先遍历

*问题描述: 建立图的存储结构(图的类型可以是有向图、无向图、有向网、无向网,学生可以任选两种类型),能够输入图的顶点和边的信息,并存储到相应存储结构中,而后输出图的邻接矩阵。 1、邻接矩阵表示法: 设G=(V,E)是一个图,其中V={V1,V2,V3…,Vn}。G的邻接矩阵是一个他有下述性质的n阶方阵: 1,若(Vi,Vj)∈E 或∈E; A[i,j]={ 0,反之 图5-2中有向图G1和无向图G2的邻接矩阵分别为M1和M2: M1=┌0 1 0 1 ┐ │ 1 0 1 0 │ │ 1 0 0 1 │ └0 0 0 0 ┘ M2=┌0 1 1 1 ┐ │ 1 0 1 0 │ │ 1 1 0 1 │ └ 1 0 1 0 ┘ 注意无向图的邻接是一个对称矩阵,例如M2。 用邻接矩阵表示法来表示一个具有n个顶点的图时,除了用邻接矩阵中的n*n个元素存储顶点间相邻关系外,往往还需要另设一个向量存储n个顶点的信息。因此其类型定义如下: VertexType vertex[MAX_VERTEX_NUM]; // 顶点向量 AdjMatrix arcs; // 邻接矩阵 int vexnum, arcnum; // 图的当前顶点数和弧(边)数 GraphKind kind; // 图的种类标志

若图中每个顶点只含一个编号i(1≤i≤vnum),则只需一个二维数组表示图的邻接矩阵。此时存储结构可简单说明如下: type adjmatrix=array[1..vnum,1..vnum]of adj; 利用邻接矩阵很容易判定任意两个顶点之间是否有边(或弧)相联,并容易求得各个顶点的度。 对于无向图,顶点Vi的度是邻接矩阵中第i行元素之和,即 n n D(Vi)=∑A[i,j](或∑A[i,j]) j=1 i=1 对于有向图,顶点Vi的出度OD(Vi)为邻接矩阵第i行元素之和,顶点Vi 的入度ID(Vi)为第i列元素之和。即 n n OD(Vi)=∑A[i,j],OD(Vi)=∑A[j,i]) j=1j=1 用邻接矩阵也可以表示带权图,只要令 Wij, 若或(Vi,Vj) A[i,j]={ ∞, 否则。 其中Wij为或(Vi,Vj)上的权值。相应地,网的邻接矩阵表示的类型定义应作如下的修改:adj:weightype ; {weightype为权类型} 图5-6列出一个网和它的邻接矩阵。 ┌∞31∞∞┐ │∞∞51∞│ │∞∞∞∞∞│ │∞∞6∞∞│ └∞322∞┘ (a)网(b)邻接矩阵 图5-6 网及其邻接矩阵 对无向图或无向网络,由于其邻接矩阵是对称的,故可采用压缩存贮的方法,

邻接表转换成邻接矩阵

请输入节点数和弧数:3 3 第1 个节点信息:5 第2 个节点信息:6 第3 个节点信息:7 第1 条弧的弧尾和弧头的位置:1 2 第2 条弧的弧尾和弧头的位置:2 3 第3 条弧的弧尾和弧头的位置:1 3 图的邻接表表示为: [1,5]-->[3,7]-->[2,6]-->^ [2,6]-->[3,7]-->[1,5]-->^ [3,7]-->[1,5]-->[2,6]-->^ 交换后是:: 图的邻接矩阵表示为: 0 1 1 1 0 1 1 1 0 请按任意键继续. . . 代码是: #include #include #define MAXV 100 typedef struct { int no; int info; }vertextype; typedef struct { int num; int edges[MAXV][MAXV]; // vertextype vexs[MAXV]; }mgraph; struct arcnode { int adjvex; int info; struct arcnode *nextarc; }; struct vexnode { int data; struct arcnode *firstarc; }; struct graph

{ int vexnum,arcnum; vexnode vexpex[100]; }; struct graph *creatgraph() { int i,s,d; struct graph *g; struct arcnode *p,*q; g = (struct graph *)malloc(sizeof(struct graph)); printf("请输入节点数和弧数:"); scanf("%d%d", &g->vexnum, &g->arcnum); for(i=1; i<=g->vexnum; i++) { printf("第%d 个节点信息:",i); scanf("%d", &g->vexpex[i].data); g->vexpex[i].firstarc = NULL; } for(i=1; i<=g->arcnum; i++) { p = (struct arcnode *)malloc(sizeof(struct arcnode)); q = (struct arcnode *)malloc(sizeof(struct arcnode)); printf("第%d 条弧的弧尾和弧头的位置:",i); scanf("%d%d",&s,&d); p->adjvex = d; p->info = g->vexpex[d].data; p->nextarc = g->vexpex[s].firstarc; g->vexpex[s].firstarc = p; q->adjvex = s; q->info = g->vexpex[s].data; q->nextarc = g->vexpex[d].firstarc; g->vexpex[d].firstarc = q; } return g; //return graph! } void changeto(graph *G, mgraph &g) { int i,j; arcnode *m; g.num = G->vexnum; for(i = 1; i<=G->vexnum; i++) for(j = 1; j<=G->vexnum; j++) g.edges[i][j] = 0;

相关文档
最新文档