每日一題——有向網的鄰接矩陣、鄰接表、逆鄰接表建立、列印及深度、廣度遍歷
阿新 • • 發佈:2018-12-22
有向網的三種建立和深度廣度遍歷
#include <iostream> #include <iomanip> using namespace std; #define MAX_VERTEX 20 //最大頂點個數 #define INFINITY 0 //表示極大值 int visited[MAX_VERTEX] = { 0 }; //鄰接矩陣 typedef struct { int vertexnum; int arcnum; int arcs[MAX_VERTEX][MAX_VERTEX]; char vertex[MAX_VERTEX]; }AdjMatrix; //邊結構 typedef struct ArcNode{ int adjvex; //頂點 int weight; //權值 ArcNode *next; }ArcNode; //頂點結構 typedef struct VertexNode { char vexdata; ArcNode *head; }VertexNode; //鄰接表 typedef struct { VertexNode vertex[MAX_VERTEX]; int vertexnum; int arcnum; }AdjList; //佇列結點 typedef struct qNode { int data; qNode *next; }QueueNode; //佇列 typedef struct queue { QueueNode *front; QueueNode *rear; }Queue; //初始化佇列 Queue* InitQueue() { Queue *Q; QueueNode *qNode; Q = (Queue*)malloc(sizeof(Queue)); qNode = (QueueNode*)malloc(sizeof(QueueNode)); qNode->next = NULL; Q->front = Q->rear = qNode; return Q; } //判空 int isEmpty(Queue *Q) { if (Q->front == Q->rear) return 1; return 0; } //入隊 void InQueue(Queue *Q, int x) { QueueNode *temp; if (temp = (QueueNode*)malloc(sizeof(QueueNode))) { temp->data = x; temp->next = NULL; Q->rear->next = temp; Q->rear = temp; } } //出隊 void OutQueue(Queue *Q, int *x) { QueueNode *temp; if (!isEmpty(Q)) { temp = Q->front->next; Q->front->next = temp->next; *x = temp->data; free(temp); if (Q->front->next == NULL) Q->rear = Q->front; } } //獲取頂點對應的位置 int LocateVexByAdjMatrix(AdjMatrix *G, char v) { for (int i = 1; i <= G->vertexnum; i++) { if (G->vertex[i] == v) return i; } return 0; } //建立圖 G1-->鄰接矩陣 G2-->鄰接表 G3-->逆鄰接表 void creatGragh(AdjMatrix *G1,AdjList *G2, AdjList *G3) { cout << "輸入圖的頂點數和邊數:" << endl; cin >> G1->vertexnum >> G1->arcnum; G2->vertexnum = G1->vertexnum; G2->arcnum = G1->arcnum; G3->vertexnum = G1->vertexnum; G3->arcnum = G1->arcnum; cout << "輸入頂點資訊:" << endl; for (int i = 1; i <= G1->vertexnum; i++) { cin >> G1->vertex[i]; G2->vertex[i].vexdata = G1->vertex[i]; G3->vertex[i].vexdata = G1->vertex[i]; } for (int i = 1; i <= G1->vertexnum; i++) {//初始化鄰接矩陣 for (int j = 1; j <= G1->vertexnum; j++) { G1->arcs[i][j] = INFINITY; } } for (int i = 1; i <= G2->vertexnum; i++) { G2->vertex[i].head = NULL; G3->vertex[i].head = NULL; } ArcNode *cur1, *cur2, *pre1 = NULL, *pre2 = NULL; cout << "輸入頭和尾結點及權值:" << endl; for (int i = 1; i <= G1->arcnum; i++) { char chead; char ctail; int weight; cin >> chead >> ctail >> weight; int head = LocateVexByAdjMatrix(G1, chead); int tail = LocateVexByAdjMatrix(G1, ctail); G1->arcs[head][tail] = weight; cur1 = (ArcNode*)malloc(sizeof(ArcNode)); cur1->adjvex = tail; cur1->weight = weight; pre1 = G2->vertex[head].head; if (G2->vertex[head].head == NULL) { G2->vertex[head].head = cur1; pre1 = cur1; pre1->next = NULL; } else { pre1->next = cur1; pre1 = cur1; pre1->next = NULL; } cur2 = (ArcNode*)malloc(sizeof(ArcNode)); cur2->adjvex = head; cur2->weight = weight; pre2 = G3->vertex[tail].head; if (G3->vertex[tail].head == NULL) { G3->vertex[tail].head = cur2; pre2 = cur2; pre2->next = NULL; } else { pre2->next = cur2; pre2 = cur2; pre2->next = NULL; } } } //列印鄰接表 void showGraghByAdjList(AdjList *G) { for (int i = 1; i <= G->vertexnum; i++) {//列印頂點資訊 ArcNode *p = G->vertex[i].head; cout << G->vertex[i].vexdata << "->"; while (p) { cout << G->vertex[p->adjvex].vexdata << " "; p = p->next; } cout << endl; } } //列印矩陣圖 void showGraghByAdjMatrix(AdjMatrix *G) { cout << setw(8) << endl; for (int i = 1; i <= G->vertexnum; i++) {//列印頂點資訊 cout << G->vertex[i] << setw(4); } cout << endl; for (int i = 1; i <= G->vertexnum; i++) {//列印鄰接矩陣 cout << G->vertex[i] << setw(4); for (int j = 1; j <= G->vertexnum; j++) { cout << G->arcs[i][j] << setw(4); } cout << endl; } } //各頂點的入度、出度和度 void degree(AdjMatrix *G) { for (int i = 1; i <= G->vertexnum; i++) { int count = 0, out_count = 0, in_count = 0; for (int j = 1; j <= G->vertexnum; j++) { if (G->arcs[i][j] != INFINITY) out_count++; if (G->arcs[j][i] != INFINITY) in_count++; count = out_count + in_count; } cout << G->vertex[i] << " " << out_count << " " << in_count << " " << count << endl; } } //一次深度優先遍歷 void DFS(AdjMatrix *G, int start) { cout << G->vertex[start]; visited[start] = 1; for (int i = 1; i <= G->vertexnum; i++) { if (G->arcs[start][i] != INFINITY && visited[i] == 0) { DFS(G, i); } } } //深度遍歷 void DFSTraverse(AdjMatrix *G) { int count = 0; for (int i = 1; i <= G->vertexnum; i++) visited[i] = 0; for (int i = 1; i <= G->vertexnum; i++) { if(!visited[i]) { count++; DFS(G, i); } } } //一次廣度遍歷 void BFS(AdjMatrix *G, int start) { cout << G->vertex[start]; visited[start] = 1; Queue *q = InitQueue(); InQueue(q, start); while (!isEmpty(q)) { int top = q->front->data; OutQueue(q, &top); for (int i = 1; i <= G->vertexnum; i++) { if (G->arcs[start][i] != INFINITY && visited[i] == 0) { cout << G->vertex[i]; visited[i] = 1; InQueue(q, i); } } } } //廣度遍歷 void BFSTraverse(AdjMatrix *G) { for (int i = 1; i <= G->vertexnum; i++) visited[i] = 0; for (int i = 1; i <= G->vertexnum; i++) if (!visited[i]) BFS(G, i); } //主函式 int main() { AdjMatrix *G1; G1 = (AdjMatrix*)malloc(sizeof(AdjMatrix)); AdjList *G2; G2 = (AdjList*)malloc(sizeof(AdjList)); AdjList *G3; G3 = (AdjList*)malloc(sizeof(AdjList)); //建立圖 creatGragh(G1, G2, G3); cout << "列印鄰接矩陣:" << endl; showGraghByAdjMatrix(G1); cout << "列印鄰接表:" << endl; showGraghByAdjList(G2); cout << "列印逆鄰接表:" << endl; showGraghByAdjList(G3); //列印度 cout << "打印出度、入度、度:" << endl; degree(G1); //深度遍歷 cout << "深度遍歷:" << endl; DFSTraverse(G1); cout << endl; //廣度遍歷 cout << "廣度遍歷:" << endl; BFSTraverse(G1); cout << endl; free(G1); free(G2); free(G3); system("pause"); return 0; }