圖的表示方法:
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;
}
}
}