1.图的存储方式
图的存储方式有邻接矩阵,邻接链表,十字链表等,邻接矩阵表示法通常将图G中的结点编为1,2,3…V,然后构造一个V*V的矩阵a[V][V],邻接矩阵的空间需求是O(V^2).对于无向图,邻接矩阵是一个对称矩阵,有时为了减少空间需求,可以存储半个矩阵。邻接矩阵也可以存储权重图,矩阵中的元素代表权重值,如果两个结点之间没有边,可以将对应的权重值设置为-1或者一个不可能的值。
对于这个无向图,邻接矩阵的存储方式为:
邻接矩阵的代码为:
# include <iostream> using namespace std; # include <stdlib.h> # define NUM 10 # define ARG 10 struct graph{ int num; //结点的数目 int arc; //边的数目 int a[NUM][NUM]; //邻接矩阵 char name[NUM]; //节点的名称 }; int main() { void create(graph &g); void print(graph &g); graph g; create(g); print(g); system("pause"); return 0; } int locate(graph &g,char a) { int i=0; for(i=0;i<g.num;i++) if (g.name[i]==a) return i; return -1; } void create(graph &g) { int i,j; cout<<"input num of nodes and num of edges"<<endl; cin>>g.num>>g.arc; for(i=0;i<g.num;i++) cin>>g.name[i]; for(i=0;i<NUM;i++) //初始矩阵初始化 for(j=0;j<NUM;j++) g.a[i][j]=0; for(i=0;i<g.arc;i++) { char a,b; int i,j,w; cout<<"input name of nodes"<<endl; cin>>a>>b>>w; i=locate(g,a); j=locate(g,b); g.a[i][j]=w; g.a[j][i]=w; } } void print(graph &g) //打印图,即为打印矩阵的元素 { int i,j; for(i=0;i<g.num;i++){ for(j=0;j<g.num;j++) cout<<g.a[i][j]<<"\t"; cout<<endl; } }
2.邻接链表
邻接链表时链式的存储结构,对图中每个节点建立一个单链表,链表的头结点是图中的各个节点,头结点和其余结点由两个域组成,分别为data和next指针。头结点的data存放的是节点的名称,普通的结点data存放的是结点序号。
上面的有向图可以用邻接链表表示,示意图为:
程序为:
# include <iostream> using namespace std; # include <stdlib.h> # define NUM 10 struct anode{ //普通结点 int data; anode *next; }; struct bnode{ //头节点 char name; anode *next; }; struct graph{ int num; int arc; bnode arr[NUM]; }; int main() { void print(graph &g); void create(graph &g); graph g; create(g); print(g); system("pause"); return 0; } int locate(graph &g,char a) //找到节点的位置 { int i=0; for(;i<g.num;i++) { if (g.arr[i].name==a) return i; } return -1; } void create(graph &g) { cout<<"input the num of nodes and num of edges"<<endl; cin>>g.num>>g.arc; int i=0; for(;i<g.num;i++) { cout<<"input the names of nodes"<<endl; cin>>g.arr[i].name; g.arr[i].next=NULL; } for(i=0;i<g.arc;i++) { char a,b; cout<<"input node a and node b"<<endl; cin>>a>>b; int i=locate(g,a); int j=locate(g,b); anode *p=new anode; p->data=j; p->next=g.arr[i].next; g.arr[i].next=p; } } void print(graph &g) //打印图 { int i=0; while(g.arr[i].next!=NULL&&i<NUM) { cout<<g.arr[i].name<<":"; anode *e=g.arr[i].next; while(e) { cout<<e->data; e=e->next; } i++; cout<<endl; } }
3十字链表
十字链表时有向图的另外一种链式存储方式,它是把邻接链表和逆邻接链表结合起来得到的一种链表,十字链表的普通节点有四个域,tail,head,hlink,tlink,头节点有三个域,data,firstin和firstout.
十字链表的程序为:
# include <iostream> using namespace std; # include <stdlib.h> # define NUM 10 struct anode //普通结点 { int tail,head; anode *hlink,*tlink; }; struct bnode{ //头结点 char name; anode *firstin,*firstout; }; struct graph{ bnode arr[NUM]; int num; int arc; }; int main() { void create(graph &g); graph g; create(g); system("pause"); return 0; } int locate (graph &g,char a) { int i=0; for(;i<g.num;i++) { if(g.arr[i].name==a) return i; } return -1; } void create(graph &g) { cout<<"input the num of nodes and edges"<<endl; cin>>g.num>>g.arc; int i,j; for(i=0;i<g.num;i++){ cout<<"input the names of nodes"<<endl; cin>>g.arr[i].name; g.arr[i].firstin=g.arr[i].firstout=NULL; } for (j=0;j<g.num;j++) { char a,b; cout<<"input the node a and node b"<<endl; cin>>a>>b; int i=locate(g,a); int j=locate(g,b); anode *p=new anode; //*p= {i,j,g.arr[j].firstin,g.arr[i].firstout}; p->tail=i; //插入新的结点 p->head=j; p->hlink=g.arr[j].firstin; p->tlink=g.arr[i].firstout; g.arr[i].firstout=g.arr[j].firstin=p; } }
原文:http://blog.csdn.net/u011608357/article/details/20860209