圖的基本操作和實現
圖的基本操作與實現
(1)自選儲存結構,輸入含n個頂點(用字元表示頂點)和e條邊的圖G;
(2)求每個頂點的度,輸出結果;
(3) 指定任意頂點x為初始頂點,對圖G作DFS遍歷,輸出DFS頂點序列(提示:使用一個棧實現DFS);
(4) 指定任意頂點x為初始頂點,對圖G作BFS遍歷,輸出BFS頂點序列(提示:使用一個佇列實現BFS);
(5) 輸入頂點x,查詢圖G:若存在含x的頂點,則刪除該結點及與之相關連的邊,並作DFS遍歷(執行操作3);否則輸出資訊“無x”;
(6) 判斷圖G是否是連通圖,輸出資訊“YES”/“NO”;
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define maxSize 100
using namespace std;
int Count=0;
const int Max=50;
typedef char type;
bool visited[100] = { false };
typedef struct ///定義資料結構:棧
{
int *top;
int *base;
int Size;
}Stack;
typedef struct ///定義資料結構:佇列
{
int *Front;
int *Rear;
int Size;
} Queue;
typedef struct ///定義資料結構:圖
{
type vexs[Max];
bool arcs[Max][Max];
int vexnum,arcnum;
} graph;
void InitStack(Stack &s) ///對棧進行初始化
{
if(!(s.top=s.base=(int *)malloc(maxSize*sizeof(int))))
return ;
s.Size=maxSize;
}
void push(Stack &s,int e) ///入棧:將元素e壓入棧
{
*s.top=e;
s.top++;
}
void pop(Stack &s) ///出棧:棧頂指標減一
{
if(s.base==s.top)
return ;
s.top--;
}
int top(Stack s) ///返回棧頂元素
{
s.top--;
return *s.top;
}
void InitQueue(Queue &q) ///初始化佇列
{
if(!(q.Front=q.Rear=(int *)malloc(maxSize*sizeof(int))))
return ;
q.Size=maxSize;
}
void Q_push(Queue &q,int e) ///入佇列:將元素e入佇列
{
*q.Rear=e;
q.Rear++;
}
int Q_pop(Queue &q) ///出佇列:返回隊頭元素,隊頭指標加一
{
int e;
if(q.Front==q.Rear)
return 0;
e=*q.Front;
q.Front++;
return e;
}
void Create(graph *g) ///建立鄰接矩陣並輸出
{
int i,j;
memset(g->arcs,0,sizeof(g->arcs));
for(i=0; i<g->arcnum; ++i)
{
int x,y;
cin>>x>>y;
g->arcs[x][y]=1;
g->arcs[y][x]=1;
}
cout<<"無向鄰接表矩陣為:"<<endl;
for(i=0; i<g->vexnum; i++)
{
for(j=0; j<g->vexnum; j++)
cout<<g->arcs[i][j]<<" ";
cout<<endl;
}
}
void Du(graph *g) ///統計每個頂點的度
{
int i,j;
for(i=0; i<g->vexnum; i++)
{
int amount=0;
for(j=0; j<g->vexnum; ++j)
if(g->arcs[i][j])
++amount;
cout<<"頂點"<<g->vexs[i]<<"的度為"<<amount<<endl;
}
}
void DFS(graph *g,int k) ///DFS深度優先搜尋
{
int t,i;
Stack s;
InitStack(s);
cout<<g->vexs[k]<<" ";
visited[k]=true;
push(s,k);
while(s.base!=s.top)
{
t=top(s);
if(i==g->vexnum) ///如果內層迴圈未找到沒被訪問的元素,則出棧
pop(s);
for(i=0; i<g->vexnum; i++)
{
if(g->arcs[t][i]==1&&visited[i]==false) ///找出鄰接矩陣第t+1行中第一個未被訪問的元素
{
visited[i]=true; ///找到後標誌為1,並輸出,入棧
cout<<g->vexs[i]<<" ";
push(s,i);
break; ///找到之後跳出內層迴圈,返回外層迴圈起始處,重複之前操作
}
}
}
}
void BFS(graph *g, int k) ///BFS廣度優先搜尋
{
Queue q;
InitQueue(q);
visited[k]=true;
cout<<g->vexs[k]<<" ";
Q_push(q,k);
while(q.Front!=q.Rear)
{
int t=Q_pop(q);
for(int w=0; w<g->vexnum; w++)
{
if (g->arcs[t][w]!=0&&visited[w]==false) ///找出鄰接矩陣中t+1行所有未被訪問的元素
{
visited[w]=true; ///每找到一個標誌為1併入佇列
cout<<g->vexs[w]<<" ";
Q_push(q,w);
}
}
}
}
void Is_in_graph(graph *g,char ch) ///查詢圖中是否存在頂點ch
{
int i,j,k;
for(i=0; i<g->vexnum; i++) ///遍歷頂點陣列
if(ch==g->vexs[i])
break;
if(i==g->vexnum) ///如果迴圈正常結束則i=g->vexnum,此時說明不存在該頂點
{
printf("無%c",ch);
return ;
}
else
{
for(j=0; j<g->vexnum; j++) ///如果存在,則將與頂點相關的邊覆蓋
for(k=0; k<g->vexnum; k++)
{
if(j>=i&&k>=i)
g->arcs[j][k]=g->arcs[j+1][k+1];
if(j>=i&&k<i)
g->arcs[j][k]=g->arcs[j+1][k];
if(j<i&&k>=i)
g->arcs[j][k]=g->arcs[j][k+1];
}
}
for(j=0; j<g->vexnum; j++) ///覆蓋該頂點
if(j>=i)
g->vexs[j]=g->vexs[j+1];
g->vexnum--;
cout<<"刪除該頂點後剩餘頂點為:\n";
for(j=0; j<g->vexnum; j++)
cout<<g->vexs[j]<<" ";
cout<<endl;
cout<<"刪除後鄰接矩陣為:\n";
for(j=0; j<g->vexnum; j++)
{
for(k=0; k<g->vexnum; k++)
cout<<g->arcs[j][k]<<" ";
cout<<endl;
}
cout<<"從第一個頂點開始的DFS遍歷為:\n";
DFS(g,0);
}
void Is_connect(graph *g,int k) ///利用DFS搜尋的思想遍歷圖,每遍歷一個頂點計數加一
{
visited[k]=true;
Count++;
for(int i=0; i<g->vexnum; i++)
if(g->arcs[k][i]==1&&visited[i]==false)
{
Is_connect(g,i);
}
}
void main_menu() ///主選單
{
cout<<"-----------------------------------\n";
cout<<"---------程式主選單----------------\n";
cout<<"-----------------------------------\n";
cout<<"---------1圖的創立及鄰接矩陣-------\n";
cout<<"---------2查詢圖中各頂點的度-------\n";
cout<<"---------3DFS遍歷圖----------------\n";
cout<<"---------4BFS遍歷圖----------------\n";
cout<<"---------5查詢頂點是否在圖中-------\n";
cout<<"---------6判斷是否為連通圖---------\n";
cout<<"---------7退出---------------------\n";
cout<<"---------Enter鍵返回選單------------\n";
cout<<"-----------------------------------\n";
cout<<"---------請選擇:(1-7)--------------\n";
}
int main()
{
int i,num;
char ch;
graph g;
while(1)
{
system("cls");
main_menu();
scanf("%d",&num);
system("cls");
switch(num) ///通過輸入1-7呼叫不同的功能
{
case 1:
printf("1圖的創立及鄰接矩陣\n\n");
printf("請輸入頂點的個數:");
cin>>g.vexnum;
cout<<endl;
printf("請輸入邊的條數:");
cin>>g.arcnum;
printf("請輸入各頂點:");
for(i=0; i<g.vexnum; ++i)
cin>>g.vexs[i];
cout<<endl;
printf("請輸入各條邊i-j:\n");
Create(&g);
printf("輸入任意鍵返回主選單:");
system("pause");
break;
case 2:
printf("2查詢圖中各頂點的度\n\n");
Du(&g);
printf("輸入任意鍵返回主選單:");
system("pause");
break;
case 3:
printf("3DFS遍歷圖\n\n");
printf("請輸入開始的頂點:");
cin>>ch;
cout<<endl;
for(i=0;i<g.vexnum;i++)
if(ch==g.vexs[i])
break;
if(i>=g.vexnum)
{
printf("輸入數字有誤!");
printf("輸入任意鍵返回主選單:");
system("pause");
break;
}
printf("從該點開始DFS搜尋為:");
DFS(&g,i);
cout<<endl;
memset(visited,0,sizeof(visited)); ///將訪問標誌陣列初始化為0
printf("輸入任意鍵返回主選單:");
system("pause");
break;
case 4:
printf("4BFS遍歷圖\n\n");
printf("請輸入開始的頂點:");
cin>>ch;
cout<<endl;
for(i=0;i<g.vexnum;i++)
if(ch==g.vexs[i])
break;
if(i>=g.vexnum)
{
printf("輸入數字有誤!");
printf("輸入任意鍵返回主選單:");
system("pause");
break;
}
printf("從該點開始BFS搜尋為:");
BFS(&g,i);
cout<<endl;
memset(visited,0,sizeof(visited)); ///將訪問標誌陣列初始化為0
printf("輸入任意鍵返回主選單:");
system("pause");
break;
case 5:
printf("5查詢頂點是否在圖中\n\n");
printf("請輸入要查詢的頂點:");
cin>>ch;
cout<<endl;
Is_in_graph(&g,ch);
cout<<endl;
memset(visited,0,sizeof(visited)); ///將訪問標誌陣列初始化為0
printf("輸入任意鍵返回主選單:");
system("pause");
break;
case 6:
printf("6判斷是否為連通圖\n\n");
Is_connect(&g,0);
if(Count==g.vexnum)
printf("YES!");
else
printf("NO!");
cout<<endl;
Count=0;
memset(visited,0,sizeof(visited)); ///將訪問標誌陣列初始化為0
printf("輸入任意鍵返回主選單:");
system("pause");
break;
case 7:
printf("退出成功");
return 0;
}
}
}
相關文章
- 有向圖的基本演算法-Java實現演算法Java
- 資料庫表的基本操作和編碼格式設定資料庫
- Kafka ACL實現架構以及實操案例剖析Kafka架構
- Spring XmlBeanFactory 容器的基本實現SpringXMLBean
- Iptables 實操
- redis實現分散式鎖---實操---問題解決Redis分散式
- 「實操」結合圖資料庫、圖演算法、機器學習、GNN 實現一個推薦系統資料庫演算法機器學習GNN
- promise基本實現思路Promise
- 樹-BST基本實現
- ROS基本程式實現ROS
- Ruby 探針的基本實現原理
- Java講解RPC的基本實現JavaRPC
- Promise 基本方法的簡單實現Promise
- 非常詳細地Hive的基本操作和一些注意事項Hive
- 圖資料庫驅動的基礎設施運維實操資料庫運維
- 前端實操案例丨如何實現JS向Vue傳值前端JSVue
- 每日一發沒有節操的圖
- 函式實操函式
- springboot的netty程式碼實操Spring BootNetty
- Istio的流量管理(實操三)
- 滲透之——asp圖片木馬的製作和使用
- Redis 如何實現庫存扣減操作和防止被超賣?Redis
- 【演算法】連結串列的基本操作和高頻演算法題演算法
- 從零手寫實現 tomcat-03-基本的 socket 實現Tomcat
- Promise實現的基本原理(一)Promise
- Promise實現的基本原理(二)Promise
- Spring原始碼之容器的基本實現Spring原始碼
- SPA路由實現的基本原理路由
- jQuery實現簡易商城系統專案實操詳解jQuery
- 作為產品經理,你需要了解的基本演算法知識和實操演算法
- 發一張沒有節操的圖片
- Node相關實操
- 前端css實現最基本的時間軸前端CSS
- 圖的基本概念
- 從0到1,手把手帶你開發截圖工具ScreenCap------001實現基本的截圖功能
- Git命令實操記錄Git
- Mysql表分割槽實操MySql
- Web Components 系列(十)—— 實現 MyCard 的基本佈局Web