数据结构7——图形(图形的存储)

图具有的特点是:每个结点有零个或者多个前驱结点,并且有零个或者多个后驱结点。

图的存储方式分为邻接矩阵和邻接表。而邻接矩阵适合于稠密图中,邻接表适合于稀疏图形中。

同时图又分为:有向图,无向图。

结点与结点之间相连是为1,如果不想连则定义为零。

1:邻接矩阵

主要是邻接矩阵存储的设计方式:图的结点信息存储在线性表中,

                 图的边权值信息存储在二维数组中。

定义一个设计图形的各种方法的类,包括对于边,结点元素的增删。

  1 package com.hone.graph;
  2
  3 import com.hone.linearlist.SeqList;
  4
  5 public class AdjMWGraph {
  6
  7     //定义一个全局变量当不连接的时候定义权重值
  8     static final int maxWeight=1000;
  9
 10     private  SeqList vertices;                    //用顺序表来存储结点
 11     private int [][] edge;                        //用二维数组来存储边
 12     private int numOfEdges;                        //边的个数
 13
 14     //定义一个构造函数用于初始化结点的属性,对于有n个结点的无向图,有n*n个结点可以参考
 15     public AdjMWGraph(int maxV){
 16         vertices = new SeqList(maxV);                 //创建顺序表vertices
 17         edge=new int[maxV][maxV];                    //创建二维数组edge
 18         for (int i = 0; i < maxV; i++) {
 19             for (int j = 0; j < maxV; j++) {
 20                 if (i==j) {
 21                      edge[i][j]=0;                    //无向图顺序矩阵存储的时候对角为0
 22                 }else{
 23                     edge[i][j]= maxWeight;
 24                 }
 25             }
 26         }
 27         numOfEdges = 0;
 28     }
 29
 30
 31     //定义一个方法用于返回结点的个数
 32     public int  getNumOfVertices(){
 33         return vertices.size();
 34     }
 35
 36     //定义一个方法用于返回边的个数
 37     public int getNumOfEdges(){
 38         return numOfEdges;
 39     }
 40
 41     //获得结点v的数据元素
 42     public Object getValue(int v)throws Exception{
 43         return vertices.getDate(v);
 44     }
 45
 46     //返回   边<v1,v2>之间的权值
 47     public int getWeight(int v1, int v2){
 48         if (v1<0||v1 >= vertices.size()||v2<0||v2>=vertices.size()) {
 49             System.out.println("参数越界,请输入正确的参数");
 50         }
 51         return edge[v1][v2];
 52     }
 53
 54     //将 某个结点插入        调用顺序表中的插入函数    并且在顺序表的末端插入函数
 55     public void insetVertex(Object vertex)throws Exception{
 56         vertices.insert(vertices.size(), vertex);
 57     }
 58
 59     //插入边<v1,v2> 并且权值为weight
 60     public void insertEdge(int v1,int v2,int weight)throws Exception{
 61         if (v1<0||v1 >= vertices.size()||v2<0||v2>=vertices.size()) {
 62             System.out.println("参数越界,请输入正确的参数");
 63         }
 64         edge[v1][v2]= weight;                //重置边的权值
 65         numOfEdges++;                        //边的个数+1
 66     }
 67
 68     //删除边<v1,v2>        在定义顺序矩阵的时候就规定权值为无穷大的时候边就不存在的,
 69     public void deleteEdge(int v1, int v2)throws Exception{
 70         if (v1<0||v1 >= vertices.size()||v2<0||v2>=vertices.size()) {
 71             System.out.println("参数越界,请输入正确的参数");
 72         }
 73         if (edge[v1][v2]==maxWeight||v1==v2) {
 74             System.out.println("该边不存在!");
 75         }
 76         edge[v1][v2]=maxWeight;                        //将边的权重设为无穷大
 77         numOfEdges--;
 78     }
 79
 80     //取结点v的第一个邻结点,如果存在则返回结点的下标序号,否则返回-1
 81     public int getFirstNeighbor(int v)throws Exception{
 82         if (v <0||v >= vertices.size()) {
 83             System.out.println("参数越界,请输入正确的参数");
 84         }
 85         for (int col = 0; col <vertices.size(); col++) {
 86             if (edge[v][col]>0&&edge[v][col]<maxWeight) {
 87                 return col;
 88             }
 89         }
 90         return -1;
 91     }
 92
 93
 94     //取出结点v1的邻接点v2后的邻接点,如果存在该结点则返回结点的下标值,否则返回-1
 95     public int getNextNeighbor(int v1,int v2)throws Exception{
 96         if (v1 <0||v1 >= vertices.size()||v2 <0||v2 >= vertices.size()) {
 97             System.out.println("参数越界,请输入正确的参数");
 98         }
 99         for (int col = v2+1; col <vertices.size(); col++) {
100             if (edge[v1][col]>0&&edge[v1][col]<maxWeight) {
101                 return col;
102             }
103         }
104         return -1;
105     }
106
107     //连通图的深度优先遍历
108     public void DFS(int v,boolean[] visited, Visit vs)throws Exception{
109         //其中visited中0表示未访问,1表示已经访问
110         vs.print(getValue(v));
111         visited[v]=true;
112
113         int w=getFirstNeighbor(v);            //获得v的第一个邻接点
114         while(w!=-1){                        //判断v是否有邻接点,并且判断邻接点是否被访问过
115             if (!visited[w]) {
116                 DFS(w, visited, vs);
117             }
118             w=getNextNeighbor(v, w);        //取出下一个邻接点
119
120         }
121     }
122
123     //连通图的广度优先遍历    类似于层序遍历用队列来遍历
124     public void BFS(int v,boolean[] visited, Visit vs)throws Exception{
125         int u,w;
126
127         SeqQueue queue=new SeqQueue();
128         vs.print(getValue(v));
129         visited[v]=true;
130
131         //将结点v压入到队列queue中去
132         queue.append(new Integer(v));
133         while(queue.notEmpty()){
134             u=(Integer)queue.delete();            //出队列
135             w=getFirstNeighbor(u);                //并且取出u的第一个邻接点w
136             //判断w是否存在,并且w没有被访问过
137             while(w!=-1){
138                 if (!visited[w]) {
139                     vs.print(getValue(w));
140                     visited[w]=true;
141                     queue.append(w);             //将结点w入队列中
142                 }
143                 //获得结点u的邻接点w的一下一个邻接结点
144                 w=getNextNeighbor(u, w);
145             }
146         }
147     }
148 }

设计一个类用于存储图新的边,以及结点信息。

 1 package com.hone.graph.test;
 2
 3 import com.hone.graph.AdjMWGraph;
 4
 5 public class RowColWeight {
 6     int row;            //行下标
 7     int col;            //列下标
 8     int weight;            //权重
 9
10     //定义一个构造函数用于初始化参数
11     public RowColWeight(int r, int c,int w){
12         row=r;
13         col=c;
14         weight=w;
15     }
16
17     //static 成员函数,给参数创建AdjMWGraph类对象g,v为结点的数据元素集合,n为结点的个数,rc为边的集合,e为边的个数
18
19     public static void createGraph(AdjMWGraph g, Object[] v,
20             int n, RowColWeight[] rc,int e) throws Exception{
21         //在图g中插入n个结点
22         for(int i=0; i<n;i++){
23             g.insetVertex(v[i]);
24         }
25         //在图g中插入e个边
26         for (int j = 0; j < e; j++) {
27             g.insertEdge(rc[j].row, rc[j].col, rc[j].weight);
28         }
29
30     }
31
32 }

测试图形的信息:

 1 package com.hone.graph.test;
 2
 3 import com.hone.graph.AdjMWGraph;
 4 import com.hone.graph.Visit;
 5
 6 public class TestSearch {
 7
 8
 9     public static void main(String[] args) {
10         final int maxVertices=100;
11         Visit vs=new Visit();
12
13         AdjMWGraph graph=new AdjMWGraph(maxVertices);
14         int n=5,e=5;
15         //定义结点元素的集合
16         Character[] a={new Character(‘A‘),
17                        new Character(‘B‘),
18                        new Character(‘C‘),
19                        new Character(‘D‘),
20                        new Character(‘E‘),
21         };
22
23         RowColWeight[] rowColWeights={new RowColWeight(0, 1, 10),
24                                     new RowColWeight(0, 4, 20),
25                                     new RowColWeight(1, 3, 30),
26                                     new RowColWeight(2, 1, 40),
27                                     new RowColWeight(3, 2, 50),
28
29         };
30         try {
31             RowColWeight.createGraph(graph, a, n, rowColWeights, e);
32             System.out.println("结点的个数为:"+graph.getNumOfVertices());
33             System.out.println("边的个数为:"+graph.getNumOfVertices());
37
38         } catch (Exception e1) {
39             e1.printStackTrace();
40         }
41
42
43     }
44
45 }
时间: 2024-10-11 09:41:29

数据结构7——图形(图形的存储)的相关文章

数据结构--树(定义与存储结构)

树基本定义 树的定义 数是具有n个节点的有限集.如图即是一个树形结构. 节点分类 节点的度:一个节点拥有的子节点即成为节点的度,比如A节点,有B和C两个子节点,那么A节点的度=2. 叶节点(终端节点):没有子节点的节点,比如G.H.I.... 如图: 节点间关系 孩子节点:某一个节点的子节点称为孩子节点.比如B.C节点是A节点的孩子节点. 双亲节点:与孩子节点相反.比如,A节点是B.C的双亲节点. 兄弟节点:同一个双亲节点的孩子节点,之间称为兄弟节点.比如,B.C为兄弟节点. 如图: 树的存储结

javascript实现数据结构: 串的块链存储表示

和线性表的链式存储结构相类似,也可采用链式方式存储串值.由于串结构的特殊性--结构中的每个数据元素是一个字符,则用链表存储串值时,存在一个"结点大小"的问题,即每个结点可以存放一个字符,也可以存放多个字符. 下面是结点大小为4(即每个结点存放4个字符)的链表: head --> (a) --> (b) --> (c) --> ... --> (i) 当结点大小大于1时,由于串长不一定是结点大小的整倍数,则链表中的最后一个结点不一定全被串值占满,此时通常补上

1、数据结构的基本逻辑结构、存储结构和运算

数据结构的基本逻辑结构.存储结构和运算 1.基本逻辑结构 集合结构.线性结构.树形结构和图状结构 2.基本存储结构 线性存储:需要一块连续的内存地址空间,相关元素一次存储 链接存储:不需要连续的地址空间,每个节点包含元素和链接两个部分,元素存储数据值,链接存储下一个节点的地址 3.基本运算 ·创建运算 ·清除运算 ·插入运算 ·搜索运算(根据值返回位置) ·更新运算 ·访问运算(根据位置返回值) ·遍历运算 1.数据结构的基本逻辑结构.存储结构和运算,布布扣,bubuko.com

数据结构--二叉树(定义与存储结构)

什么是二叉树 是具有n个节点的有限集合,由一个根节点和两棵互不相交二叉树组成.如图 从名字简单理解,就是具有2个树叉的树形结构,当然这不是绝对的,正如上图所示,我也可以只有一个树叉. 二叉树具有五种基本形态: (1)空二叉树 (2)只有一个根结点的二叉树 (3)只有左子树 (4)只有右子树 (5)既有左子树又有右子树 完全二叉树 这种二叉树,是二叉树中常用的专业术语,不是说一个完整的二叉树就是完全二叉树,这种二叉树叫满二叉树,如图 简单理解就像图片中,完全二叉树中每个节点的编号,都能映射到满二叉

数据结构--图--图的数组存储表示,深度优先搜索遍历和广度优先搜索遍历

图有四种存储结构:数组,邻接表,十字链表,邻接多重表.下面以数组为存储结构来实现图的深度优先搜索遍历和广度优先搜索遍历.其中广度优先搜索遍历中有用到STL中的queue,注意头文件的包含.具体代码如下: //图的数组(邻接矩阵)存储表示和深度优先遍历 const int MAX_VERTEX_NUM=20; //最大顶点数 typedef enum {DG,DN,UDG,UDN} GraphKind ;//(有向图,有向网,无向图,无向网) typedef int VRType; typedef

浅谈数据结构之线性表链式存储(二)

前面我们所讲的线性表的顺序存储结构,它是有优缺点,最大的缺点是插入与删除时需移动大量的元素,这显然需要耗费许多时间.这时,我们就引入线性表的链式存储结构,它的特点是:用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的.这就意味着,这些数据可以存在内存中未被占用的任意位置上,即当线性表进行插入与删除时就不需要移动大量的元素了,节约了时间. 链式结构中,除了需要存储数据元素的信息外,还要存储它的后继元素的存储地址.我们把存储数据元素信息的域称为数据域,把存储直接后继

数据结构所涉及的数据存储结构类型

大类分别为: 线性表,栈,队列,树,二叉树,图 线性表: 顺序存储结构的定义 typedef struct { ElemType data[maxsize];            //存放顺序表中的元素 int length;                       //存放顺序表的长度 }SqList;                     //顺序表的类型定义 链式存储结构的定义 typedef struct LNode             //定义单链表的节点类型 { Elem

【C语言--数据结构】线性表链式存储结构

直接贴代码 头文件 #ifndef __LINKLIST_H__ #define __LINKLIST_H__ typedef void LinkList; typedef struct _tag_LinkListNode { LinkList* next; }LinkListNode; LinkList* LinkList_create(); void LinkList_Destroy(LinkList* pstList); void LinkList_Clear(LinkList* pstL

Java数据结构-树及树的存储结构

树的定义:n(n>=0)个节点的有限集. n=0时称为空树. n!=0时为非空树,有且仅有一个特定的节点--根:n>1时,其它节点可以分为m(m>0)个互不相交的有限集T1~Tm,其中每一个集合本身又是一棵树,并且称为根的子树. 树的一些基本术语: 树的结点:由一个数据元素和若干个指向其子树的分支组成. 结点的度:结点所拥有的子树的个数(即分支数)称为该结点的度. 叶子结点:度为0的结点称为叶子结点,或者称为终端结点. 分支结点:度不为0的结点称为分支结点,或者称为非终端结点.一棵树的结

数据结构--图的定义和存储结构

图的定义 图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成.注意:在图结构中,不允许没有顶点,在定义中,如果V是顶点的集合,则强调了顶点集合V的有穷非空. 在图中,若不存在顶点到其自身的边,且同一条边不重复出现,则称这样的图为简单图. 图的存储结构 邻接矩阵 考虑到图是由顶点和边或者弧两部分组成的.合在一起比较困难,那就自然地考虑到分两个结构来分别存储.顶点不分大小.主次,所以用一个一位数组来存储是很不错的选择.而边或者弧是顶点与顶点之间的关系,一维搞不定,那就考虑用一个二维数组来存