数据结构-练习 9 图的存储 之邻接链表

前言:图是树的扩展,本博文主要讲述图的存储。

            图的存储包括:图的邻接矩阵,图的邻接链表,以及十字链表。

          1,图的邻接矩阵,无非开辟一个一维数组和一个二维数组。一维数组用于存放图的顶点信息,二维数组用于存放图的连接信息,之前做过一个传感网的项目。记得是用一个二维数组存放路由之间的信息的,因为路由的信息是无向的,所以当时只用了一半。这个很简单,直接跳过;

           2,图的邻接链表,数组和链表的组合。示意图如下:

                                                                                       

                                                                                                                                图  1

图分有向和无向的,分别如下图:图2 和 图 3。

                                 

                                                                                                                                                                    图   2


                                    

图 3

       图2 与图1对应。我们知道,要存储图2,如果按图1的方式的存储,在数据结构上必须具备两种,静态数组和链表。

       数组的下标表示的就是节点的顺序,里面存储的是对应的数据和一个指向链表的指针。



      定义的数据结构:

    

struct edgeNode;
/*
define the struct
*/
//定义数据结构
 struct DataNode
{
 char savedData;
 //int weight;the weight of node
 edgeNode* next;
 DataNode()
  {
  savedData='\0';
  next=NULL;
  }
};

 struct edgeNode
{
 int sequence;//存放数组的下标,表示数据之间的关系
 edgeNode* next;
};


//节点数目
const int NUM=7;
DataNode  GraphList[NUM];



建立图表:

 

  

//建立图
void createGraph(DataNode * graphl)
{
 cout<<"请输入7个数据节点:"<<endl;
 char inputChar;
 int  nodeOne;
 int  nodeTwo;
 for(int i=0;i<NUM;++i)
  {
   cin>>inputChar;
   graphl[i].savedData=inputChar;
  }


 //建立 边
 cout<<"请输入要链接的两个节点:"<<endl;
 while(1)
  {
 cin>>nodeOne;
 cin>>nodeTwo;
 if(nodeOne==-1&&nodeTwo==-1)
     return;
 edgeNode *newEdgeN1=new edgeNode();
 newEdgeN1->sequence=nodeTwo;
 newEdgeN1->next=graphl[nodeOne].next;
 graphl[nodeOne].next=newEdgeN1;

 edgeNode* newEdgeN2=new edgeNode();
 newEdgeN2->sequence=nodeOne;
 newEdgeN2->next=graphl[nodeTwo].next;
 graphl[nodeTwo].next=newEdgeN2;
 
  
  }
 
 
}


 

 

//释放内存
void deleteMem(DataNode * graphl)
{
  edgeNode *p=NULL;
  edgeNode *TEMP=NULL;
  for(int i=0;i<NUM;++i)
  {
  p=GraphList[i].next;
  while(p)
  {
   TEMP=p;
   p=p->next;
   delete TEMP;
  

  }
}
}


测试:

 

 

int main()
{
  

createGraph(GraphList);
cout<<"输出链表序列:"<<endl;
for(int i=0;i<NUM;++i)
{
 
 edgeNode *p=GraphList[i].next;

 
 cout<<i<<":"<<GraphList[i].savedData<<"  ";

 while(p)
 {
 cout<< p->sequence<<",";
  p=p->next;
 }
 cout<<"\n"; 
}
return 0;
}

结果:按图2 的方式输入字符。只不过输入的字符不是V0,V1......

 

      

3图的十字链表:有向图的出度和入度十字链表,都只能定位出或是入的节点,要想同时定位出入的节点,很简单,把二者结合起来就可以。不再做介绍。         

 

posted @ 2013-06-07 20:25  爱生活,爱编程  阅读(409)  评论(0编辑  收藏  举报