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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

数据结构——图的深度遍历

發(fā)布時(shí)間:2023/12/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构——图的深度遍历 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

圖的遍歷方式有兩種,

  • 深度優(yōu)先
  • 廣度優(yōu)先
  • 深度優(yōu)先采用的是遞歸的方式來(lái)來(lái)實(shí)現(xiàn),思想如下:

    假設(shè)給定圖G的初態(tài)是所有頂點(diǎn)均未曾訪(fǎng)問(wèn)過(guò)。在G中任選一頂點(diǎn)v為初始出發(fā)點(diǎn)(源點(diǎn)),
    **則深度優(yōu)先遍歷可定義如下:
    首先訪(fǎng)問(wèn)出發(fā)點(diǎn)v,并將其標(biāo)記為已訪(fǎng)問(wèn)過(guò);然后依次從v出發(fā)搜索v的每個(gè)鄰接點(diǎn)w。若w未曾訪(fǎng)問(wèn)過(guò),則以w為新的出發(fā)點(diǎn)繼續(xù)進(jìn)行深度優(yōu)先遍歷,直至圖中所有和源點(diǎn)v有路徑相通的頂點(diǎn)(亦稱(chēng)為從源點(diǎn)可達(dá)的頂點(diǎn))均已被訪(fǎng)問(wèn)為止。若此時(shí)圖中仍有未訪(fǎng)問(wèn)的頂點(diǎn),則另選一個(gè)尚未訪(fǎng)問(wèn)的頂點(diǎn)作為新的源點(diǎn)重復(fù)上述過(guò)程,直至圖中所有頂點(diǎn)均已被訪(fǎng)問(wèn)為止。**
    流程圖如下:
    因?yàn)椴捎玫氖沁f歸調(diào)用,那就需要有兩個(gè)函數(shù),主要的遞歸調(diào)用的函數(shù)是放在private中的;在public有一個(gè)函數(shù)來(lái)調(diào)用這個(gè)遞歸函數(shù),
    public函數(shù)流程圖如下:

    private 函數(shù)如下:

    在這里用的臨界表的形式來(lái)存儲(chǔ)無(wú)向圖;
    圖的結(jié)構(gòu)體的定義和我圖的十字鏈表表示法中圖的結(jié)構(gòu)體定義差不多,只是增加了一個(gè)標(biāo)記位。用來(lái)標(biāo)記這個(gè)結(jié)點(diǎn)是不是被訪(fǎng)問(wèn)過(guò)。圖示如下:
    還是要定義兩個(gè)結(jié)構(gòu)體,圖的鄰接表是采用數(shù)組+鏈表的方式來(lái)實(shí)現(xiàn)的。那鏈表的結(jié)構(gòu)體定義如下:

    數(shù)組的結(jié)構(gòu)體定義如下:

    在這里是用無(wú)向圖圖的實(shí)現(xiàn)的,其實(shí)有向圖的實(shí)現(xiàn)和這個(gè)差不多少,還是也可以采用圖的鄰接表來(lái)實(shí)現(xiàn),其實(shí)基本一樣,大體是一樣的,還是要設(shè)置標(biāo)記位。我是采用下面的圖的測(cè)試的。


    代碼如下:

    // GraphList.cpp // 深度優(yōu)先遍歷 // // Created by 橘子和香蕉 on 2018/11/25. // Copyright ? 2018 橘子和香蕉. All rights reserved. ///*遇到的問(wèn)題:1:首先是添加邊;用戶(hù)輸入的兩個(gè)結(jié)點(diǎn),先要判斷哪個(gè)結(jié)點(diǎn)是新添加的,是倆都是,還是一個(gè)是,,然后設(shè)置位置。添加結(jié)點(diǎn)先是將數(shù)據(jù)放在數(shù)組,然后要將它添加到相應(yīng)的鏈表中去,那就要申請(qǐng)新結(jié)點(diǎn),我就是在初始化結(jié)點(diǎn)的時(shí)候沒(méi)有將結(jié)點(diǎn)中指針設(shè)置為NULL,才導(dǎo)致了我之后的錯(cuò)誤,想想就覺(jué)得自己蠢。 2:在刪除結(jié)點(diǎn)的時(shí)候要判斷這個(gè)結(jié)點(diǎn)還有沒(méi)有鄰結(jié)點(diǎn),若是沒(méi)有,就要?jiǎng)h除這個(gè)結(jié)點(diǎn),*/#include <iostream> using namespace std; #define dataType char #define MAXSIZE 100 typedef struct node{int position;node *next; }node; typedef struct Box{dataType data;node *out;bool isAccess; }Box; class Graph{ private:Box base[MAXSIZE];int vertexNum;int edgeNum;int locate(dataType data);void deleteEdgePrivate(int startPosition,int endPositon);void def(int position);bool isNotHaveNevNode(dataType data);void moveNode(dataType data);public:~Graph();void init(int vertexNum,int edgeNum);void create();void printNode(dataType data);void printGraph();void addEdge(dataType start,dataType end);void deleteEdge(dataType start,dataType end);void depthErgodic(dataType data);}; Graph::~Graph(){for (int i = 0; i<vertexNum; i++) {node *p= base[i].out;node *h = p;while ( p != NULL) {h = p->next;if(h == NULL) return;delete p;p = h->next;}}// delete []base; } void Graph::init(int vertexNum, int edgeNum){this->vertexNum = vertexNum;this->edgeNum = edgeNum; } int Graph::locate(dataType data){for (int i = 0; i<vertexNum; i++) {if(base[i].data == data){return i;}}return -1; } void Graph::create(){cout<<"create Graph begin\n";for (int i = 0; i<vertexNum; i++) {cout<<"input node data\n";cin>>base[i].data;base[i].out = NULL;base[i].isAccess = false;}node *startNode,*endNode;int startPosition;int endPosition;dataType start;dataType end;for (int i = 0; i<edgeNum; i++) {cout<<"input edge start and end\n";cin>>start>>end;startPosition = locate(start);endPosition = locate(end);//創(chuàng)建鏈表。先是創(chuàng)建start指向end;//在創(chuàng)建end指向start;endNode = new node;endNode->position = endPosition;endNode->next = base[startPosition].out;base[startPosition].out = endNode;startNode = new node;startNode->position = startPosition;startNode->next = base[endPosition].out;base[endPosition].out = startNode;}} void Graph::printNode(dataType data){int position = locate(data);if(position == -1){cout<<"data is not exist\n";return;}else{node *h = base[position].out;cout<<"the data of"<<data<<":\t";while (h!=NULL) {cout<<base[h->position].data<<"\t";h=h->next;}}cout<<"\n"; } void Graph::printGraph(){for (int i = 0; i<vertexNum; i++) {printNode(base[i].data);} } void Graph::addEdge(dataType start, dataType end){int startPosition = locate(start);int endPosition = locate(end);if(startPosition == -1){base[vertexNum].data = start;base[vertexNum].out = NULL;startPosition = vertexNum;init(vertexNum +1 , edgeNum+1);}if(endPosition == -1){base[vertexNum].data = end;base[vertexNum].out = NULL;endPosition = vertexNum;init(vertexNum +1 , edgeNum+1);}if(startPosition == -1 && endPosition == -1){base[vertexNum].data = start;startPosition = vertexNum;init(vertexNum +1 , edgeNum+1);base[vertexNum].data = end;endPosition = vertexNum;init(vertexNum +1 , edgeNum+1);}node* endNode = new node;endNode->position = endPosition;endNode->next = base[startPosition].out;base[startPosition].out = endNode;node* startNode = new node;startNode->position = startPosition;startNode->next = base[endPosition].out;base[endPosition].out = startNode;}void Graph::deleteEdge(dataType start, dataType end){/*a:刪除的時(shí)候要判斷倆結(jié)點(diǎn)的位置,然后一個(gè)一個(gè)的刪除,先是刪除start 到end這條表然后接著刪除end到start這條邊;其實(shí)刪除的操作都是一樣的,然后我就將刪除的操作獨(dú)立了出來(lái),寫(xiě)了一個(gè)函數(shù),放到private中去,刪除start 到end和刪除end到start只不過(guò)就是在函數(shù)調(diào)用的時(shí)候顛倒就好了,但是這只限于無(wú)向圖。*/int startPosition= locate(start);int endPositon = locate(end);if(startPosition ==-1 || endPositon == -1){cout<<"node is not exist\n";return;}deleteEdgePrivate( startPosition,endPositon);deleteEdgePrivate(endPositon, startPosition);if( isNotHaveNevNode(start) == true){moveNode(start);}if(isNotHaveNevNode(end) == true){moveNode(end);} }void Graph::deleteEdgePrivate(int startPosition,int endPositon){int n = 0;node * p = base[startPosition].out;node *h = base[startPosition].out;while (p != NULL) {if(n ==0 && p->position == endPositon ) {base[startPosition].out = p->next;delete p;return;}n++;if(n != 0 && p->position == endPositon){h->next = p->next;cout<<" "<<base[p->position].data<<endl;delete p;return ;}h = p;p = p->next;} }void Graph::depthErgodic(dataType data){int position = locate(data);position == -1?cout<<"the data is not exist\n":cout<<"";def(position);} void Graph::def(int position){node *p;cout<<base[position].data<<endl;base[position].isAccess = true;p = base[position].out;while (p != NULL) {if(base[p->position].isAccess == false){def(p->position);}p = p->next;} } /*p判斷還有沒(méi)有鄰結(jié)點(diǎn)*/ bool Graph::isNotHaveNevNode(dataType data){int position = locate(data);return base[position].out == NULL?true:false; } /*移動(dòng)數(shù)據(jù)*/ void Graph::moveNode(dataType data){int position = locate(data);for (int i = position; i<vertexNum ; i++) {base[i].data = base[i+1].data;base[i].out = base[i+1].out;base[i].isAccess = base[i+1].isAccess;}this->vertexNum -= 1; } int main(){Graph a;a.init(4, 4);a.create(); // a.printNode('b'); // a.printGraph();a.addEdge('d', 'e');a.printNode('d');a.printNode('e');a.deleteEdge('d', 'e');a.printNode('e');return 1; }

    總結(jié)

    以上是生活随笔為你收集整理的数据结构——图的深度遍历的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。