日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深度、广度优先生成树(C完整代码)

發布時間:2024/10/14 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度、广度优先生成树(C完整代码) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫在前面:博主是一位普普通通的19屆雙非軟工在讀生,平時最大的愛好就是聽聽歌,逛逛B站。博主很喜歡的一句話花開堪折直須折,莫待無花空折枝:博主的理解是頭一次為人,就應該做自己想做的事,做自己不后悔的事,做自己以后不會留有遺憾的事,做自己覺得有意義的事,不浪費這大好的青春年華。博主寫博客目的是記錄所學到的知識并方便自己復習,在記錄知識的同時獲得部分瀏覽量,得到更多人的認可,滿足小小的成就感,同時在寫博客的途中結交更多志同道合的朋友,讓自己在技術的路上并不孤單。

目錄:
1.生成樹和生成森林
???? ?? 深度、廣度優先生成樹
???? ?? 非連通圖的生成森林
2.深度優先生成森林
???? ?? 深度優先生成森林簡介
???? ?? 深度優先生成森林完整代碼實現(c語言)

3.廣度優先生成森林
???? ?? 廣度優先生成森林簡介
???? ?? 廣度優先生成樹完整代碼實現(C語言)

1.生成樹和生成森林

1.1深度、廣度優先生成樹

其實在對無向圖進行遍歷的時候,遍歷過程中所經歷過的圖中的頂點和邊的組合,就是圖的生成樹或者生成森林。

例如:

當使用深度優先搜索算法時,假設 V1 作為遍歷的起始點,涉及到的頂點和邊的遍歷順序為(不唯一):

此種遍歷順序構建的生成樹為:

由深度優先搜索得到的樹為深度優先生成樹。同理,廣度優先搜索生成的樹為廣度優先生成樹,無向圖以頂點 V1 為起始點進行廣度優先搜索遍歷得到的樹,如下所示:

1.2非連通圖的生成森林

非連通圖在進行遍歷時,實則是對非連通圖中每個連通分量分別進行遍歷,在遍歷過程經過的每個頂點和邊,就構成了每個連通分量的生成樹。

非連通圖中,多個連通分量構成的多個生成樹為非連通圖的生成森林。

2.深度優先生成森林

2.1深度優先生成森林簡介

非連通圖在遍歷生成森林時,可以采用孩子兄弟表示法將森林轉化為一整棵二叉樹進行存儲。

2.2深度優先生成森林完整代碼實現(c語言)

#include <stdio.h> #include <stdlib.h> #define MAX_VERtEX_NUM 20 //頂點的最大個數 #define VRType int //表示頂點之間的關系的變量類型 #define VertexType int //圖中頂點的數據類型 typedef enum{false,true}bool; //定義bool型常量 bool visited[MAX_VERtEX_NUM]; //設置全局數組,記錄標記頂點是否被訪問過typedef struct {VRType adj; //對于無權圖,用 1 或 0 表示是否相鄰;對于帶權圖,直接為權值。 }ArcCell,AdjMatrix[MAX_VERtEX_NUM][MAX_VERtEX_NUM];typedef struct {VertexType vexs[MAX_VERtEX_NUM]; //存儲圖中頂點數據AdjMatrix arcs; //二維數組,記錄頂點之間的關系int vexnum,arcnum; //記錄圖的頂點數和弧(邊)數 }MGraph; //孩子兄弟表示法的鏈表結點結構 typedef struct CSNode{VertexType data;struct CSNode * lchild;//孩子結點struct CSNode * nextsibling;//兄弟結點 }*CSTree,CSNode; //根據頂點本身數據,判斷出頂點在二維數組中的位置 int LocateVex(MGraph G,VertexType v){int i=0;//遍歷一維數組,找到變量vfor (; i<G.vexnum; i++) {if (G.vexs[i]==v) {break;}}//如果找不到,輸出提示語句,返回-1if (i>G.vexnum) {printf("no such vertex.\n");return -1;}return i; } //構造無向圖 void CreateDN(MGraph *G){scanf("%d,%d",&(G->vexnum),&(G->arcnum));getchar();for (int i=0; i<G->vexnum; i++) {scanf("%d",&(G->vexs[i]));}for (int i=0; i<G->vexnum; i++) {for (int j=0; j<G->vexnum; j++) {G->arcs[i][j].adj=0;}}for (int i=0; i<G->arcnum; i++) {int v1,v2;scanf("%d,%d",&v1,&v2);int n=LocateVex(*G, v1);int m=LocateVex(*G, v2);if (m==-1 ||n==-1) {printf("no this vertex\n");return;}G->arcs[n][m].adj=1;G->arcs[m][n].adj=1;//無向圖的二階矩陣沿主對角線對稱} } int FirstAdjVex(MGraph G,int v) {//查找與數組下標為v的頂點之間有邊的頂點,返回它在數組中的下標for(int i = 0; i<G.vexnum; i++){if( G.arcs[v][i].adj ){return i;}}return -1; } int NextAdjVex(MGraph G,int v,int w) {//從前一個訪問位置w的下一個位置開始,查找之間有邊的頂點for(int i = w+1; i<G.vexnum; i++){if(G.arcs[v][i].adj){return i;}}return -1; } void DFSTree(MGraph G,int v,CSTree*T){//將正在訪問的該頂點的標志位設為truevisited[v]=true;bool first=true;CSTree q=NULL;//依次遍歷該頂點的所有鄰接點for (int w=FirstAdjVex(G, v); w>=0; w=NextAdjVex(G, v, w)) {//如果該臨界點標志位為false,說明還未訪問if (!visited[w]) {//為該鄰接點初始化為結點CSTree p=(CSTree)malloc(sizeof(CSNode));p->data=G.vexs[w];p->lchild=NULL;p->nextsibling=NULL;//該結點的第一個鄰接點作為孩子結點,其它鄰接點作為孩子結點的兄弟結點if (first) {(*T)->lchild=p;first=false;}//否則,為兄弟結點else{q->nextsibling=p;}q=p;//以當前訪問的頂點為樹根,繼續訪問其鄰接點DFSTree(G, w, &q);}} } //深度優先搜索生成森林并轉化為二叉樹 void DFSForest(MGraph G,CSTree *T){(*T)=NULL;//每個頂點的標記為初始化為falsefor (int v=0; v<G.vexnum; v++) {visited[v]=false;}CSTree q=NULL;//遍歷每個頂點作為初始點,建立深度優先生成樹for (int v=0; v<G.vexnum; v++) {//如果該頂點的標記位為false,證明未訪問過if (!(visited[v])) {//新建一個結點,表示該頂點CSTree p=(CSTree)malloc(sizeof(CSNode));p->data=G.vexs[v];p->lchild=NULL;p->nextsibling=NULL;//如果樹未空,則該頂點作為樹的樹根if (!(*T)) {(*T)=p;}//該頂點作為樹根的兄弟結點else{q->nextsibling=p;}//每次都要把q指針指向新的結點,為下次添加結點做鋪墊q=p;//以該結點為起始點,構建深度優先生成樹DFSTree(G,v,&p);}} } //前序遍歷二叉樹 void PreOrderTraverse(CSTree T){if (T) {printf("%d ",T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->nextsibling);}return; } int main() {MGraph G;//建立一個圖的變量CreateDN(&G);//初始化圖CSTree T;DFSForest(G, &T);PreOrderTraverse(T);return 0; }運行結果: //輸入 13,13 1 2 3 4 5 6 7 8 9 10 11 12 13 1,2 1,3 1,6 1,12 2,13 4,5 7,8 7,10 7,9 8,10 11,12 11,13 12,13 //輸出 1 2 13 11 12 3 6 4 5 7 8 10 9

運行程序,拿下圖 中的非連通圖為例

構建的深度優先生成森林,使用孩子兄弟表示法表示為:

圖中,3 種顏色的樹各代表一棵深度優先生成樹,使用孩子兄弟表示法表示,也就是將三棵樹的樹根相連,第一棵樹的樹根作為整棵樹的樹根。

3.廣度優先生成森林

3.1廣度優先生成森林簡介

非連通圖采用廣度優先搜索算法進行遍歷時,經過的頂點以及邊的集合為該圖的廣度優先生成森林。

拿下圖非連通圖為例

通過廣度優先搜索得到的廣度優先生成森林用孩子兄弟表示法

3.2廣度優先生成樹完整代碼實現(C語言)

#include <stdio.h> #include <stdlib.h> #define MAX_VERtEX_NUM 20 //頂點的最大個數 #define VRType int //表示頂點之間的關系的變量類型 #define InfoType char //存儲弧或者邊額外信息的指針變量類型 #define VertexType int //圖中頂點的數據類型 typedef enum{false,true}bool; //定義bool型常量 bool visited[MAX_VERtEX_NUM]; //設置全局數組,記錄標記頂點是否被訪問過 typedef struct {VRType adj; //對于無權圖,用 1 或 0 表示是否相鄰;對于帶權圖,直接為權值。InfoType * info; //弧或邊額外含有的信息指針 }ArcCell,AdjMatrix[MAX_VERtEX_NUM][MAX_VERtEX_NUM];typedef struct {VertexType vexs[MAX_VERtEX_NUM]; //存儲圖中頂點數據AdjMatrix arcs; //二維數組,記錄頂點之間的關系int vexnum,arcnum; //記錄圖的頂點數和弧(邊)數 }MGraph;typedef struct CSNode{VertexType data;struct CSNode * lchild;//孩子結點struct CSNode * nextsibling;//兄弟結點 }*CSTree,CSNode;typedef struct Queue{CSTree data;//隊列中存放的為樹結點struct Queue * next; }Queue;//根據頂點本身數據,判斷出頂點在二維數組中的位置 int LocateVex(MGraph * G,VertexType v){int i=0;//遍歷一維數組,找到變量vfor (; i<G->vexnum; i++) {if (G->vexs[i]==v) {break;}}//如果找不到,輸出提示語句,返回-1if (i>G->vexnum) {printf("no such vertex.\n");return -1;}return i; } //構造無向圖 void CreateDN(MGraph *G){scanf("%d,%d",&(G->vexnum),&(G->arcnum));for (int i=0; i<G->vexnum; i++) {scanf("%d",&(G->vexs[i]));}for (int i=0; i<G->vexnum; i++) {for (int j=0; j<G->vexnum; j++) {G->arcs[i][j].adj=0;G->arcs[i][j].info=NULL;}}for (int i=0; i<G->arcnum; i++) {int v1,v2;scanf("%d,%d",&v1,&v2);int n=LocateVex(G, v1);int m=LocateVex(G, v2);if (m==-1 ||n==-1) {printf("no this vertex\n");return;}G->arcs[n][m].adj=1;G->arcs[m][n].adj=1;//無向圖的二階矩陣沿主對角線對稱} }int FirstAdjVex(MGraph G,int v) {//查找與數組下標為v的頂點之間有邊的頂點,返回它在數組中的下標for(int i = 0; i<G.vexnum; i++){if( G.arcs[v][i].adj ){return i;}}return -1; } int NextAdjVex(MGraph G,int v,int w) {//從前一個訪問位置w的下一個位置開始,查找之間有邊的頂點for(int i = w+1; i<G.vexnum; i++){if(G.arcs[v][i].adj){return i;}}return -1; }//初始化隊列 void InitQueue(Queue ** Q){(*Q)=(Queue*)malloc(sizeof(Queue));(*Q)->next=NULL; } //結點v進隊列 void EnQueue(Queue **Q,CSTree T){Queue * element=(Queue*)malloc(sizeof(Queue));element->data=T;element->next=NULL;Queue * temp=(*Q);while (temp->next!=NULL) {temp=temp->next;}temp->next=element; } //隊頭元素出隊列 void DeQueue(Queue **Q,CSTree *u){(*u)=(*Q)->next->data;(*Q)->next=(*Q)->next->next; } //判斷隊列是否為空 bool QueueEmpty(Queue *Q){if (Q->next==NULL) {return true;}return false; }void BFSTree(MGraph G,int v,CSTree*T){CSTree q=NULL;Queue * Q;InitQueue(&Q);//根結點入隊EnQueue(&Q, (*T));//當隊列為空時,證明遍歷完成while (!QueueEmpty(Q)) {bool first=true;//隊列首個結點出隊DeQueue(&Q,&q);//判斷結點中的數據在數組中的具體位置int v=LocateVex(&G,q->data);//已經訪問過的更改其標志位visited[v]=true;//遍歷以出隊結點為起始點的所有鄰接點for (int w=FirstAdjVex(G,v); w>=0; w=NextAdjVex(G,v, w)) {//標志位為false,證明未遍歷過if (!visited[w]) {//新建一個結點 p,存放當前遍歷的頂點CSTree p=(CSTree)malloc(sizeof(CSNode));p->data=G.vexs[w];p->lchild=NULL;p->nextsibling=NULL;//當前結點入隊EnQueue(&Q, p);//更改標志位visited[w]=true;//如果是出隊頂點的第一個鄰接點,設置p結點為其左孩子if (first) {q->lchild=p;first=false;}//否則設置其為兄弟結點else{q->nextsibling=p;}q=p;}}} } //廣度優先搜索生成森林并轉化為二叉樹 void BFSForest(MGraph G,CSTree *T){(*T)=NULL;//每個頂點的標記為初始化為falsefor (int v=0; v<G.vexnum; v++) {visited[v]=false;}CSTree q=NULL;//遍歷圖中所有的頂點for (int v=0; v<G.vexnum; v++) {//如果該頂點的標記位為false,證明未訪問過if (!(visited[v])) {//新建一個結點,表示該頂點CSTree p=(CSTree)malloc(sizeof(CSNode));p->data=G.vexs[v];p->lchild=NULL;p->nextsibling=NULL;//如果樹未空,則該頂點作為樹的樹根if (!(*T)) {(*T)=p;}//該頂點作為樹根的兄弟結點else{q->nextsibling=p;}//每次都要把q指針指向新的結點,為下次添加結點做鋪墊q=p;//以該結點為起始點,構建廣度優先生成樹BFSTree(G,v,&p);}} } //前序遍歷二叉樹 void PreOrderTraverse(CSTree T){if (T) {printf("%d ",T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->nextsibling);}return; } int main() {MGraph G;//建立一個圖的變量CreateDN(&G);//初始化圖CSTree T;BFSForest(G, &T);PreOrderTraverse(T);return 0; } 運行結果: //輸入 13,13 1 2 3 4 5 6 7 8 9 10 11 12 13 1,2 1,3 1,6 1,12 2,13 4,5 7,8 7,10 7,9 8,10 11,12 11,13 12,13 //輸出 1 2 13 3 6 12 11 4 5 7 8 9 10

本篇博客轉載C語言中文網

總結

以上是生活随笔為你收集整理的深度、广度优先生成树(C完整代码)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日日人人 | 午夜视频一区二区 | 另类专区亚洲 | aaa人片在线 | 久久久久人妻精品色欧美 | 性生活av| 91九色在线视频 | 久久精品a| 欧美黄色一级视频 | 久久久嫩草 | 国产一区二区三区四区五区美女 | 香蕉视频在线观看免费 | 国产做受高潮动漫 | www嫩草| 亚洲福利视频网 | 不卡一区在线 | 国产素人在线 | 蜜桃视频污 | 天天操狠狠操 | 少妇爽 | 男女交性视频播放 | 精品一区在线观看视频 | 色欲色香天天天综合网www | 亚洲系列在线 | 又污又黄的视频 | 久久久久亚洲精品 | 免费手机av | 欧美激情精品久久久久久免费 | 亚洲成人麻豆 | 人妻无码中文久久久久专区 | 日本毛片在线看 | 成人精品免费在线观看 | 91成年版| 国内av自拍 | 亚洲午夜视频 | 亚洲精品成人在线视频 | 一本大道久久 | 免费视频色| www.中文字幕在线观看 | 全部免费毛片在线播放 | 男人操女人的视频 | 福利社91| 亚洲男女av | 污网站免费在线 | 国产一级二级毛片 | 男人免费视频 | 免费中文av | 秋霞av鲁丝片一区二区 | 色婷婷国产精品 | 国产精品色综合 | 国产成人+综合亚洲+天堂 | 污视频在线观看免费 | 人妻奶水人妻系列 | 中文字幕一区二区三区四区免费看 | 亚洲精品中文字幕乱码三区91 | 国产精品天天看 | 久久精品中文闷骚内射 | 涩涩片影院 | a视频在线观看 | 一区二区三区人妻 | 91麻豆精品国产91久久久无需广告 | 欧美粗大猛烈老熟妇 | 免费看黄在线 | 天天插天天透 | 欧美女优在线 | 欧美韩一区二区 | 嫩草视频网站 | av中文字幕网站 | 国产一级特黄毛片 | 天天干天天综合 | 亚洲av无码一区二区乱孑伦as | 96超碰在线| 久久亚洲综合国产精品99麻豆精品福利 | 欧美特黄一级 | 久久99久久久久久 | 亚洲欧美一区二区视频 | 中文字幕在线播放不卡 | mm131丰满少妇人体欣赏图 | 一级全黄少妇性色生活片 | 久久国内免费视频 | 脱女学生小内内摸了高潮 | 日韩av毛片在线观看 | 91在线欧美| 日本亚洲网站 | 久久国产精品久久久久久电车 | 亚洲国产免费 | 亚洲欧洲另类 | 91抖音在线观看 | 欧美图片自拍偷拍 | 女王人厕视频2ⅴk | 国产精品视频看看 | 日韩欧美在线免费观看 | 精品国产免费一区二区三区 | 成人在线免费播放视频 | 亚洲尹人| 成人免费毛片东京热 | 午夜av在线免费观看 | 91久久精品日日躁夜夜躁欧美 | av中出|