图的最基本的两种遍历方法,参考了算法导论的两个图例。
最值得说的是:
广度优先搜索(BFS)跟树的层次遍历比较像 用了队列(Queue)来作为临时储存的媒介。
深度优先搜索(DFS)跟输的前序遍历比较像——>(preoder traversal)。
先是广度优先搜索的图例:
然后上代码 以后补充w:
先是链表形式的:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct doubleLinkList* DL;
typedef struct queue* Q;
Q Qfront = NULL, Qrear = NULL;
struct doubleLinkList{
int data;
DL prev;
DL next;
};
typedef struct queue{
int data;
Q next;
};
DL DLinsert(int data, DL head){
DL newPtr = (DL)malloc(sizeof(doubleLinkList));
newPtr->data = data;
if (head == NULL){
newPtr->prev = NULL;
newPtr->next = NULL;
head = newPtr;
}
else{
newPtr->next = head;
head->prev = newPtr;
head = newPtr;
}
return head;
}
bool isEmpty(){
if (!Qfront&&!Qrear) return true;
else return false;
}
void enqueue(int data){
Q newPtr = (Q)malloc(sizeof(queue));
newPtr->data = data;
if (isEmpty()){
Qfront = Qrear = newPtr;
newPtr->next = NULL;
}
else{
Qrear->next = newPtr;
Qrear = newPtr;
Qrear->next = NULL;
}
}
int dequeue(){
int d;
if (Qfront == NULL){
Qrear = Qfront;
printf("queue is already empty!\n\n");
exit(0);
}
Q temp = Qfront;
d = temp->data;
Qfront = Qfront->next;
if (Qrear == temp)Qrear = NULL;
free(temp);
return d;
}
int main(){
int n = 0, u = 0, temp = 0;
int * dis;
DL* arr;
DL start;
printf("enter the number of vertex:");
scanf("%d%*c", &n);
dis = (int*)calloc(n, sizeof(int));
arr = (DL*)calloc(n, sizeof(DL));
for (int i = 0; i<n; i++){
printf("enter the vertex through the node %d (-1 to end) :", i);
while (scanf("%d", &temp) && temp != -1){
arr[i] = DLinsert(temp, arr[i]);
}
printf("\n");
}
printf("enter the source node:");
scanf("%d", &temp);
printf("\n");
enqueue(temp);
while (Qfront != NULL){
u = dequeue();
start = arr[u];
while (start != NULL){
if (dis[start->data] == 0 && start->data != temp){
dis[start->data] = dis[u] + 1;
enqueue(start->data);
}
start = start->next;
}
}
for (int i = 0; i <n; i++){
printf(" %d: %d\n", i, dis[i]);
}
return 0;
}
接着是矩阵形式的:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct queue* Q;
Q Qfront = NULL, Qrear = NULL;
typedef struct queue{
int data;
Q next;
};
bool isEmpty(){
if (!Qfront&&!Qrear) return true;
else return false;
}
void enqueue(int data){
Q newPtr = (Q)malloc(sizeof(queue));
newPtr->data = data;
if (isEmpty()){
Qfront = Qrear = newPtr;
newPtr->next = NULL;
}
else{
Qrear->next = newPtr;
Qrear = newPtr;
Qrear->next = NULL;
}
}
int dequeue(){
int d;
if (Qfront == NULL){
Qrear = Qfront;
printf("queue is already empty!\n\n");
exit(0);
}
Q temp = Qfront;
d = temp->data;
Qfront = Qfront->next;
if (Qrear == temp)Qrear = NULL;
free(temp);
return d;
}
int main(){
int n = 0, u = 0, temp = 0;
int** map;
int*dis;
printf("enter the number of vertex:");
scanf("%d%*c", &n);
map = (int**)malloc(n*sizeof(int*));
for (int i = 0; i < n; i++) {
*(map + i) = (int*)malloc(n*sizeof(int));
memset(*(map + i), 0, sizeof(int)*n);
}
dis = (int*)malloc(n*sizeof(int));
memset(dis, 0, n*sizeof(int));
for (int i = 0; i<n; i++){
printf("enter the vertex through the node %d (-1 to end) :", i);
while (scanf("%d", &temp) && temp != -1){
map[i][temp] = 1;
}
printf("\n");
}
printf("enter the source node:");
scanf("%d", &temp);
printf("\n");
enqueue(temp);
while (Qfront != NULL){
u = dequeue();
for (int i = 0; i<n; i++){
if (map[u][i] == 1 && i != temp&&dis[i] == 0){
dis[i] = dis[u] + 1;
enqueue(i);
}
}
}
for (int i = 0; i <n; i++){
for (int j = 0; j<n; j++)printf("%d ", map[i][j]);
printf("\n");
}
printf("\ndis: ");
for (int i = 0; i < n; i++) printf("%d", dis[i]);
printf("\n\n");
return 0;
}
矩阵形式的output:
下面是深度优先搜索:
先上图例:
首先是链表形式的:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct doubleLinkList* DL;
typedef struct distime* dt;
int time = 0;
dt dis;
DL* arr;
struct distime{
int start = 0;
int end;
};
struct doubleLinkList{
int data;
DL prev;
DL next;
};
DL DLinsert(int data, DL head){
DL newPtr = (DL)malloc(sizeof(doubleLinkList));
newPtr->data = data;
if (head == NULL){
newPtr->prev = NULL;
newPtr->next = NULL;
head = newPtr;
}
else{
newPtr->next = head;
head->prev = newPtr;
head = newPtr;
}
return head;
}
void DFS(int i){
DL ptr;
time = time + 1;
dis[i].start = time;
ptr = arr[i];
while (ptr != NULL){
if (dis[ptr->data].start == 0)DFS(ptr->data);
ptr = ptr->next;
}
time = time + 1;
dis[i].end = time;
}
int main(){
int n = 0,temp = 0;
DL ptr;
printf("enter the number of vertex:");
scanf("%d%*c", &n);
dis = (dt)calloc(n, sizeof(distime));
arr = (DL*)calloc(n, sizeof(DL));
for (int i = 0; i<n; i++){
printf("enter the vertex through the node %d (-1 to end) :", i);
while (scanf("%d", &temp) && temp != -1){
arr[i] = DLinsert(temp, arr[i]);
}
printf("\n");
}
for (int i = 0; i<n; i++){
if (dis[i].start == 0)DFS(i);
}
for (int i = 0; i<n; i++){
printf("S:%d F:%d\n", dis[i].start, dis[i].end);
}
return 0;
}
最后是 深度优先搜索的矩阵形式:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct distime* dt;
int time = 0, n = 0;
dt dis;
int** map;
struct distime{
int start = 0;
int end;
};
void DFS(int u){
time = time + 1;
dis[u].start = time;
for (int i = 0; i<n; i++){
if (dis[i].start == 0 && map[u][i] == 1)DFS(i);
}
time = time + 1;
dis[u].end = time;
}
int main(){
int temp = 0;
printf("enter the number of vertex:");
scanf("%d%*c", &n);
dis = (dt)calloc(n, sizeof(distime));
map = (int**)malloc(n*sizeof(int*));
for (int i = 0; i < n; i++) {
*(map + i) = (int*)malloc(n*sizeof(int));
memset(*(map + i), 0, sizeof(int)*n);
}
for (int i = 0; i<n; i++){
printf("enter the vertex through the node %d (-1 to end) :", i);
while (scanf("%d", &temp) && temp != -1){
map[i][temp] = 1;
}
printf("\n");
}
for (int i = 0; i<n; i++){
if (dis[i].start == 0)DFS(i);
}
for (int i = 0; i <n; i++){
for (int j = 0; j<n; j++)printf("%d ", map[i][j]);
printf("\n");
}
printf("\n");
for (int i = 0; i<n; i++){
printf("S:%d F:%d\n", dis[i].start, dis[i].end);
}
return 0;
}
深度搜索矩阵形式的output(这回路径跟图例是完全一直的):