图的表示方法:
1.邻接矩阵法
2.邻接表法
3.索引表法
在程序应用中,多为转换为邻接表法。
例如:
可以用数组表示为:
int data[20][2]={{1,2},{2,1},{1,3},{3,1},
{2,4},{4,2},{2,5},{5,2},
{3,6},{6,3},{3,7},{7,3},
{4,5},{5,4},{6,7},{7,6},
{5,8},{8,5},{6,8},{8,6}};
将它用邻接表法表示:
#include<iostream>
using namespace std;
class list{
public:
int val;
class list *next;
};
list *head[9];
int main()
{
int run[9];
for(int i=0;i<9;i++)
run[i] = 0;
int data[20][2]={{1,2},{2,1},{1,3},{3,1},
{2,4},{4,2},{2,5},{5,2},
{3,6},{6,3},{3,7},{7,3},
{4,5},{5,4},{6,7},{7,6},
{5,8},{8,5},{6,8},{8,6}};
list *ptr,*newnode;
for(int i=1;i<9;i++)
{
head[i] = new list;
head[i]->val = i;
head[i]->next=NULL;
ptr = head[i];
for(int j=0;j<20;j++)
{
if(data[j][0]==i)
{
newnode = new list;
newnode->val = data[j][1];
newnode->next = NULL;
ptr->next = newnode;
ptr = ptr->next;
}
}
}
for(int i=1;i<9;i++)
{
ptr = head[i];
while(ptr)
{
cout<<ptr->val<<" ";
ptr = ptr->next;
}
cout<<endl;
}
return 0;
}
图的遍历
1.深度优先遍历
void dfs(int current) //深度优先遍历子程序
{
link ptr;
run[current]=1;
cout<<"["<<current<<"] ";
ptr=head[current]->next;
while(ptr!=NULL)
{
if (run[ptr->val]==0) //如果顶点尚未遍历,
dfs(ptr->val); //就进行dfs的递归调用
ptr=ptr->next;
}
}
2.宽度优先遍历
#include <iostream>
#include <cstdlib>
#define MAXSIZE 10 //定义队列的最大容量
using namespace std;
int front=-1; //指向队列的前端
int rear=-1; //指向队列的后端
struct list //声明图顶点的结构
{
int x; //顶点数据
struct list *next; //指向下一个顶点的指针
};
typedef struct list node;
typedef node *link;
struct GraphLink
{
link first;
link last;
};
int run[9]; //用来记录各顶点是否遍历过
int queue[MAXSIZE];
struct GraphLink Head[9];
void print(struct GraphLink temp)
{
link current=temp.first;
while(current!=NULL)
{
cout<<"["<<current->x<<"]";
current=current->next;
}
cout<<endl;
}
void insert(struct GraphLink *temp,int x)
{
link newNode;
newNode=new node;
newNode->x=x;
newNode->next=NULL;
if(temp->first==NULL)
{
temp->first=newNode;
temp->last=newNode;
}
else
{
temp->last->next=newNode;
temp->last=newNode;
}
}
//队列数据的加入
void enqueue(int value)
{
if(rear>=MAXSIZE) return;
rear++;
queue[rear]=value;
}
//队列数据的取出
int dequeue()
{
if(front==rear) return -1;
front++;
return queue[front];
}
//广度优先遍历法
void bfs(int current)
{
link tempnode; //临时的节点指针
enqueue(current); //将第一个顶点加入队列
run[current]=1; //将遍历过的顶点设置为1
cout<<"["<<current<<"]"; //打印出该遍历过的顶点
while(front!=rear) { //判断当前是否为空队列
current=dequeue(); //将顶点从队列中取出
tempnode=Head[current].first; //先记录当前顶点的位置
while(tempnode!=NULL)
{
if(run[tempnode->x]==0)
{
enqueue(tempnode->x);
run[tempnode->x]=1; //记录已遍历过
cout<<"["<<tempnode->x<<"]";
}
tempnode=tempnode->next;
}
}
}