1、3270 齐佳欣数据结构课程设计上海电力学院数据结构C+课程设计题目: 社会网络分析系统的设计与实现 学生姓名: 齐佳欣 学 号: 20103270 院系: 计算机与信息工程学院 专业年级: 信息安全2010级 2012 年6月29日一、设计题目 社会网络分析系统的设计和实现二、需求分析1)运行环境(软、硬件环境)软件:Microsoft Visual C+硬件:处理器:Intel(R)Pentium(R)CPU 内存(RAM):2.00GB 2)输入的形式和输入值的范围1.以字符数据代表社会网络的人员2.以整形数据代表社会网络人员的关系数(图的边数)3.输入数值范围(1-100)3)输出的形
2、式描述1.输出构建的邻接矩阵2.输出核心人物、活跃人物、边缘人物,小团体、桥接人物(字符形式)4)功能描述 1.根据输入的数据构建无向图的连接矩阵,以无向图的边代表两点之间的联系 2利用度的概念,找出核心人物、活跃人物和边缘人物(规定度数大于所有顶点数一半的为活跃人物,小于一半定点数的为边缘)3利用子图,找出小团体的和联系小团体的桥接人。即在图中找出连通子图,凡是属于不同连通子图的公共点都是桥接点。4.能查找任何人的交往圈子,任意给出一顶点,找出该顶点所属的连通图,即为该人的交往圈子。5)测试数据三、概要设计1)抽象数据类型定义描述(对各类的成员及成员函数进行抽象描述,参见书或ppt及实验)A
3、DT Graph is Data存放图中顶点(社会网络人物)的数组存放图中各顶点之间的边(社会网络人物的关系)的数组图中人物总数和关系总数标记数组OperationGraph初始化值:图中的人数关系数/存放图中的数组/标志顶点访问的数组动作:选择操作类型,调用图的创建函数。createUG输入:图中的顶点数(图中的人物数),图中的顶点的边(人员之间的相互联系)前置条件:构造函数调用功能:创建无向图输出:无后置条件:无向图建立Center输入:无前置条件:无向图已经建立功能:找出社会网络的核心人物输出:社会网络的核心人物后置条件:无Active输入:无前置条件:无向图建立功能:找出社会网络的活跃
4、人物输出:社会网络的活跃人物后置条件:无Border输入:无前置条件:无向图的建立功能:找出社会网络的边缘人物输出:社会网络的边缘人物后置条件:无PrintGraph输入:无前置条件:无向图建立功能:输出邻接矩阵输出:输出邻接矩阵后置条件:无DFSTraverse输入:无前置条件:无向图的建立,对标志数组进行初始化为0功能:从指定的顶点开始深度遍历输出:深度遍历序列,找出指定点的交往圈子后置条件:无DFS输入:无前置条件:无向图的建立,重新对数组进行置0处理功能:从指定的顶点开始进行深度遍历输出:输出连通图的序列后置条件:对访问过的顶点置1Group输入:无前置条件:无向图的建立,已对访问过的
5、顶点功能:从指定的顶点开始进行深度遍历输出:已标记为1的顶点后置条件:无2)功能模块设计(如主程序模块设计)1.主程序模块:连接各种功能的子模块,完成需要的操作和实现的功能。2.社会网络构建模块:按照相关步骤和要求构建无向图。3.核心人物模块:根据用户的输入,构建的相关的无向图,由度的概念程序计算出网络的核心人物。4.活跃人物模块:根据用户的输入,构建相关的无向图,由度的概念程序计算出网络的活跃人物。5.边缘人物模块:根据用户的输入,构建相关的无向图,由度的概念程序计算出网络的边缘人物。6.小团体模块:根据用户的输入,构建相关的无向图,由深度遍历程序输出遍历的序列即为小团体。3)模块层次调用关
6、系图 四、详细设计实现概要设计中定义的所有的类的定义及类中成员函数,并对主要的模块写出伪码算法。1)对类的定义:templateclass Graph public: Graph(T a,int n,int e);/构造函数,a表示数组,表示顶点的个数,e表示边数 void center(int n); /声明核心人物函数 void printGraph();/输出邻接矩阵 void active(int n);/活跃人物函数 void DFSTraverse(int v); /对图进行深度优先遍历,找出某一点所属的小团体 void border(int n);/边缘人物函数 void DFS
7、(int v);/对图的连通子图进行深度优先遍历,找出小团体 void group(int n);找出两个小团体的桥接人物 private: T vertexmaxsize;/顶点数组 int arcmaxsizemaxsize;/边数 int vertexNum,arcNum;/定点数,边数 void createUG(T a,int n,int e);/构建无向图 int *visited;/设置标志数组 ;成员函数:1)核心人物,活跃人物,边缘人物templatevoid Graph:center(int n) vertexNum=n; int i,j; int k=0; int dmm
8、axsize=0; for(i=0;ivertexNum;i+)/计算每个顶点的度数 for( j=0;jvertexNum;j+) dmi+=arcij; / int x=dm0;for (i=0; ix) x=dmi; k=i; cout该社会网络的核心人物是:vertexkendl; /templatevoid Graph:active(int n) vertexNum=n; int i,j; int dmmaxsize=0; for(i=0;ivertexNum;i+)/计算每个顶点的度数 for( j=0;jvertexNum;j+) dmi+=arcij; cout活跃人物有:;
9、for(i=0;ivertexNum/2)/规定一个顶点的度数大于定点数一半的即为活跃人物 coutvertexi endl; templatevoid Graph:border(int n) vertexNum=n; int i,j; int dmmaxsize=0; for(i=0;ivertexNum;i+)/计算每个顶点的度数 for( j=0;jvertexNum;j+) dmi+=arcij;cout边缘人物有:; for(i=0;ivertexNum;i+) if(dmivertexNum/2)/规定一个顶点的度数小于顶点一半的即为边缘人物 coutvertexi endl; 2
10、)深度优先遍历i)找出小团体间的桥接点ii)找出某一点所属的小团体template void Graph:DFSTraverse(int v) /深度优先遍历图 cout该人员是vertexv endl; cout与该人员交往的圈子是:; for (int j=0; jvertexNum; j+) if (arcv-1j=1|arcjv-1=1) / DFSTraverse(j) coutvertexj ; /团体查找template void Graph:DFS(int v) /深度优先遍历图(无向图) if (v=0)/判断是不是初始使用而不是递归调用 是的话初始化顶点标记矩阵,代表没有访
11、问过,代表访问过 for (int i=0;imaxsize;i+) visitedi=0; /visitedvertexNum=999;/表示顶点数的标记信息显示到此为止 /*for (int m=0;mvertexNum;m+)/将顶点连接情况的数组先打印出来 for (int n=0;nvertexNum;n+) if(n=vertexNum-1) coutarcmn ; coutendl; else coutarcmn ;*/ DFS(1); else if (visitedv-1=0)/判断当前结点是否被访问过,没有访问过才继续进行操作 visitedv-1=1;/立刻将该结点置为访
12、问过 coutvertexv-1 ; for (int i=v-1;ivertexNum;i+) if (arcv-1i=1)/判断两个结点之间是否连通,连通则进入其中进行遍历 DFS(i+1); else ; else ; /templatevoid Graph:group(int n)visitedn=1;for(int j=0;jvertexNum;j+) if(visitedj=1) coutvertexj ; if(arcnj=1&visitedj=0) group(j); 五、调试分析包括调试过程中遇到的问题及解决的方法、算法的时间空间复杂性分析、经验体会。1)遇到问题Q1.首先这
13、个社会网络是构建有向图还是无向图?K1.最终决定构建无向图,理由是,若构建有向图是表示两人间的相互关系,无向图是表示这两人人之间存在关系,我认为有向图可用于通讯录,用在社会网络分析图的构建上不是很妥当。Q2.标志数组已在构造函数中进行初始化,为什么还要在成员函数对各个顶点重新赋值?K2.这主要是限于本题目的要求,因为深度优先遍历调用次数大于两次,已标记过的顶点会对后续调用产生影响,所以需对其重新赋初值。Q3.如何查找小团体?K3.根据子图的定义,从某一顶点开始进行深度优先遍历,所得的连通子图序列即为该点所属的小团体。Q4.如何查找小团体间的桥接点?K4.所谓的桥接点,即属于不同小团体间的公共点
14、。以某一点开始对图深度优先遍历,得到一个连通子图,再以另一点开始进行深度优先遍历,输出已标志为1的顶点,即为两个小团体的公共点。2)算法时间空间复杂性分析答:深度优先遍历的时间复杂度O(n2) 输出遍历的时间复杂度为O(n2)3)经验体会 由于自身能力原因,感觉这道题目还是有一定难度的。题目要求中的前两问还能做出,在寻找小团体的桥接点和某一点所属的小团体中,做了很多尝试方法,结果都不尽人意,最后还是经过的老师的指点和讲解,才解得出来。主要是由于对图的概念掌握不够深刻,尤其是连通子图的深度优先遍历,并不是简单地对整个图进行遍历,这一点最开始并没有注意到。对连通子图进行深度优先遍历时,首先还是要判
15、断这一点是否有下一个连接点,如果有的话,那么继续进行遍历,如果没有,那么到此结束。而如果对整个图(可以是连通图,也可以是不连通的图)进行深度优先遍历时,还需要加上如下语句,for (int j=0; jvertexNum; j+) if (arcvj=1 & visitedj=0) DFSTraverse(j,visited); 才能将所有的点都遍历一个遍,并且保证不重复遍历。总之经过这次课程设计,发现问题,思考产生问题的原因,不断改进,最终解决问题这一过程对图这一类型的数据结构有了更加深刻的理解,加深了对其应用的认识。六 用户使用说明详细列出每一步的操作说明。1. 用户输入社会网络人物的总数
16、2. 输入社会网络人物的名称3. 输入社会网络人物的总边数4. 选择是否要知道某个人的交往圈子(1表示是,0表示否)5. 输入要知道的人的交往圈子的数字代码6. 选择是否要知道该社会网络人物的核心人物、活跃人物、边缘人物。七、 测试结果八、附录:程序设计源代码#includeusing namespace std;const int maxsize=100;templateclass Graph public: Graph(T a,int n,int e);/构造函数,a表示数组,表示顶点的个数,e表示边数 void center(int n); /声明核心人物函数 void printGra
17、ph();/输出邻接矩阵 void active(int n);/活跃人物函数 void DFSTraverse(int v); /对图进行深度优先遍历,找出某一点所属的小团体 void border(int n);/边缘人物函数 void DFS(int v);/对图的连通子图进行深度优先遍历,找出小团体 void group(int n);/找出两个小团体的桥接人物 private: T vertexmaxsize;/顶点数组 int arcmaxsizemaxsize;/边数 int vertexNum,arcNum;/定点数,边数 void createUG(T a,int n,int
18、 e);/构建无向图 int *visited;/设置标志数组 ;/构造函数templateGraph:Graph(T a,int n,int e) visited=new intvertexNum;/对标志数组进行初始化 for(int i=0;ivertexNum;i+) visitedi=0; int kind; cout该系统创建的图类型为:endl; cout-1.无向图-kind; switch(kind) case 1: createUG(a,n, e);break; default:cout输入数值错误endl; /构建无向图template void Graph:create
19、UG(T a,int n,int e)/创建无向图 vertexNum=n; /顶点数 arcNum=e; /边数 int i,j,k; for (i=0; ivertexNum; i+) vertexi=ai; for (i=0; ivertexNum; i+) /初始化邻接矩阵 for (j=0; jvertexNum; j+) arcij=0; for (k=0; karcNum; k+) /依次输入每一条边,并修改邻接矩阵的相应元素 cout请输入第k+1ij; /边依附的两个顶点的序号 arci-1j-1=1; /置有边标志 arcj-1i-1=1; /该网络的核心人物,活跃人物,边
20、缘人物templatevoid Graph:center(int n) vertexNum=n; int i,j; int k=0; int dmmaxsize=0; for(i=0;ivertexNum;i+)/计算每个顶点的度数 for( j=0;jvertexNum;j+) dmi+=arcij; / int x=dm0;for (i=0; ix) x=dmi; k=i; cout该社会网络的核心人物是:vertexkendl; /templatevoid Graph:active(int n) vertexNum=n; int i,j; int dmmaxsize=0; for(i=0
21、;ivertexNum;i+)/计算每个顶点的度数 for( j=0;jvertexNum;j+) dmi+=arcij; cout活跃人物有:; for(i=0;ivertexNum/2)/规定一个顶点的度数大于定点数一半的即为活跃人物 coutvertexi endl; templatevoid Graph:border(int n) vertexNum=n; int i,j; int dmmaxsize=0; for(i=0;ivertexNum;i+)/计算每个顶点的度数 for( j=0;jvertexNum;j+) dmi+=arcij;cout边缘人物有:; for(i=0;iv
22、ertexNum;i+) if(dmivertexNum/2)/规定一个顶点的度数小于顶点一半的即为边缘人物 coutvertexi endl; template void Graph:printGraph()/输出邻接矩阵 int i,j; for(i=0;ivertexNum;i+) for(j=0;jvertexNum;j+) coutarcijends; coutendl; /查找任意人的交往圈子template void Graph:DFSTraverse(int v) /深度优先遍历图 cout该人员是vertexv endl; cout与该人员交往的圈子是:; for (int
23、j=0; jvertexNum; j+) if (arcv-1j=1|arcjv-1=1) / DFSTraverse(j) coutvertexj ; /团体查找template void Graph:DFS(int v) /深度优先遍历图(无向图) if (v=0)/判断是不是初始使用而不是递归调用 是的话初始化顶点标记矩阵,代表没有访问过,代表访问过 for (int i=0;imaxsize;i+) visitedi=0; /visitedvertexNum=999;/表示顶点数的标记信息显示到此为止 /*for (int m=0;mvertexNum;m+)/将顶点连接情况的数组先打
24、印出来 for (int n=0;nvertexNum;n+) if(n=vertexNum-1) coutarcmn ; coutendl; else coutarcmn ;*/ DFS(1); else if (visitedv-1=0)/判断当前结点是否被访问过,没有访问过才继续进行操作 visitedv-1=1;/立刻将该结点置为访问过 coutvertexv-1 ; for (int i=v-1;ivertexNum;i+) if (arcv-1i=1)/判断两个结点之间是否连通,连通则进入其中进行遍历 DFS(i+1); else ; else ; /templatevoid Graph:group(int n)visitedn=1;for(int j=0;jvertexNum;j+) if(visitedj=1) coutvertexj ; if(arcnj=1&visitedj=0) group(j); /
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1