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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

广度优先搜索_计算机入门必备算法——广度优先遍历搜索

發(fā)布時間:2024/9/15 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 广度优先搜索_计算机入门必备算法——广度优先遍历搜索 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1、? 序言

又很久沒有學習了,上次學到哈希表又稱散列表的相關(guān)知識,這次我們學習一種新的數(shù)據(jù)結(jié)構(gòu)來建立網(wǎng)絡(luò)模型。這種數(shù)據(jù)結(jié)構(gòu)被稱作圖。首先,我們先應(yīng)該先了解一下什么是圖,其次學習第一種圖的算法,這種圖的算法被稱作是廣度優(yōu)先搜索算法(breadth-first search ,BFS)。

???????? 廣度優(yōu)先搜索算法其實就是幫助你找出兩樣東西之間的最短距離,掌握了這種算法之后,我們可以完成以下幾項內(nèi)容:

  • 編寫國際跳棋AI,計算出最少走多少步可以獲勝

  • 編寫拼寫檢查器,計算最少編輯多少個地方就可以將錯拼的單詞改成正確的單詞,如將READED改為READER需要編輯一個地方

  • 根據(jù)你的人際關(guān)系網(wǎng)絡(luò)找到關(guān)系最近的醫(yī)生

--------此示例來源于《算法圖解》

2、? 圖簡介

聽說戶縣到咸陽的大巴已經(jīng)停運了,那么我們?nèi)ハ剃柕脑捑托枰匦掠嬎懵肪€,(我們暫時排除自駕到咸陽的路線)假設(shè)我們乘坐公共交通工具前往,并且希望中間的換乘最少,可以到達的部分交通線路如下:

??我們從圖中可以發(fā)現(xiàn)想從石油大學直接到達咸陽湖景區(qū),除了自駕其它并不能一步到達景區(qū),接著我們使用兩步、三步、四步發(fā)現(xiàn)都不能直接到達景區(qū),最少也得需要五步,路線為:從石油大學東門(周南站)乘坐101路到鄠邑站,然后乘坐動車到達阿房宮站,然后乘坐1061路到達灃東第一學校站,接著換成咸陽郭杜線到達統(tǒng)一廣場站,最終不步行到達咸陽湖景區(qū)。當然還有其他到達景區(qū)的路線,但它們執(zhí)行起來路程會更遠。這個算法發(fā)現(xiàn),前往咸陽湖景區(qū)需要五步,這種問題在專業(yè)上稱為“最短路徑問題(shorterest-path problem)”。解決最短路徑的問題的算法被稱為廣度優(yōu)先搜索。

就像上圖一樣,我們將路線用圖解的形式展現(xiàn)出來,這就是圖!其實非常簡單,圖由節(jié)點和邊組成。一個節(jié)點可能與眾多節(jié)點直接相連,這些眾多節(jié)點都被稱為這個節(jié)點的鄰節(jié)點,在上圖,大十字站和亞迪路站都被稱為郭寨橋站的鄰節(jié)點。

??一句話概括起來:圖用于模擬不同的東西是如何相連的。

3、? 廣度優(yōu)先搜索

??廣度優(yōu)先搜索算法是一種可用于圖的查找算法,可以幫助回答兩類問題:

??????????從節(jié)點A出發(fā),有前往節(jié)點B的路徑嗎?

??從節(jié)點A出發(fā),前往節(jié)點B的哪條路徑最短?

舉個例子,假設(shè)你經(jīng)營著一個果園,每年秋天果子成熟了你需要將蘋果賣給他。在微信上,你在好友列表中去找這么一個人。這種查找很簡單,只需每看到一個人,然后想想他是不是收蘋果的。

假設(shè)你沒有朋友是收蘋果的,那么就必須在朋友的朋友中進行查找。然后問到信息之后立馬把他記在小本本上,這樣一來,不僅需要在朋友中進行查找,還需要在朋友的朋友中查找。如果你當前看到的朋友并不是收蘋果的,就將其加入小本本里,這就意味著你將在他的人際關(guān)系中進行查找。這種算法最終會將你整個人際關(guān)系網(wǎng)進行搜索,直到找到蘋果經(jīng)銷商,這就是廣度優(yōu)先搜索算法。

  • 廣度優(yōu)先搜索算法過程

? 在剛才的例子中,我們先從自己的朋友開始找起,后來從朋友的朋友繼續(xù)查找,自己朋友稱為一度關(guān)系,朋友的朋友稱為二度關(guān)系,顯然,一度關(guān)系優(yōu)于二度關(guān)系。

?????搜索時,肯定是先自己的朋友,其次是朋友的朋友。當然只有按添加順序查找時,才能達到搜索的目的。舉個例子,張三是自己的朋友,李四是張三的朋友,但是李四先添加到名單中時,假設(shè)張三和李四都是收蘋果的,但是由于添加順序不對,必定會先搜索李四,然后再搜索張三,這樣的話只是搜索到了蘋果經(jīng)銷商,但沒搜索到最近的朋友。

? 別忘了廣度優(yōu)先搜索需要解決兩個問題:第一個是存在嗎?第二個是最短嗎?

????但是這種按照順序存儲的數(shù)據(jù)結(jié)構(gòu)竟然存在,它的專業(yè)術(shù)語叫做“隊列”。

  • 隊列

? 數(shù)據(jù)結(jié)構(gòu)的隊列就如同我們吃飯排隊,秉承先來后到的原則,先到的先吃飯。隊列類似于棧,你不能隨機地訪問隊列中的元素,隊列只支持兩種操作:入隊和出隊。

? 隊列是一種先進先出的數(shù)據(jù)結(jié)構(gòu)(First in First Out,FIFO)

3、? 代碼實現(xiàn)

package cn.yanhao.breadthfirstsearch;/**
??* 定義圖類*/public class Graph
?{private final int ?Max_VERTS = 6;?? //圖中頂點的個數(shù)private Vertex vertexList[];??????? //用來存儲頂點的數(shù)組//用鄰接矩陣來存儲邊,數(shù)組元素表示沒有邊界,1表示有邊界private ?int adjMat[][];private int nVerts;???????? //頂點個數(shù)private QueueX queue;?????? //用隊列實現(xiàn)廣度優(yōu)先搜索/*頂點類
????? */class Vertex{public char label;public boolean wasVisited;public Vertex(char label){this.label ?= label;wasVisited = false;
???????? }
???? }
???? Graph(){//頂點數(shù)組長度初始化為20vertexList = new Vertex[Max_VERTS];//初始化20x20矩陣adjMat ?= new int[Max_VERTS][Max_VERTS];nVerts = 0; //初始化頂點個數(shù)為0
???? ????//初始化鄰接矩陣所有元素都為0,即所有頂點沒有邊for (int i = 0; i ?< Max_VERTS; i++) {for (int j = 0; j ?< Max_VERTS; j++) {adjMat[i][j] ?= 0;
???????????? }
???????? }queue = new QueueX();
???? }//將頂點添加到數(shù)組中,是否訪問位置置為wasVisited ?= false(未訪問)public ?void addVertex(char lab){//先添加在加1vertexList[nVerts++] = new Vertex(lab);
???? }//用鄰接矩陣表示邊,是對稱的,兩部分都要賦值public ?void addEdge(int start,int end){adjMat[start][end] ?= 1;adjMat[end][start] ?= 1;
???? }//打印某個頂點表示的值public ?void displayVertex(int v){
???????? System.out.print(vertexList[v].label+"");
???? }//找到與某一頂點鄰接且未被訪問的頂點public ?int getAdjUnvisitedVertex(int v){for (int i = 0; i ?< nVerts; i++) {//v頂點與i頂點相鄰且未被訪問if(adjMat[v][i] ?== 1 && vertexList[i].wasVisited ?== false){return i;
???????????? }
???????? }return -1;
???? }/**
????? * 廣度優(yōu)先搜索* 1、用remove方法檢查棧頂* 2、試圖找到這個頂點還未被訪問的鄰接點* 3、如果沒有找到,該頂點出列* 4、如果找到這樣的頂點,訪問這個頂點,并把它放入隊列中*/public void breadthFirstSearch()
???? {//第一個頂點可訪問vertexList[0].wasVisited ?= true;//打印第一個頂點的值displayVertex(0);//隊列插入第一個元素queue.insert(0);int v2;//如果隊列不為空while(!queue.isEmpty()){int v1 = queue.remove();while ((v2 = ?getAdjUnvisitedVertex(v1)) != -1){vertexList[v2].wasVisited ?= true;
???????????????? displayVertex(v2);queue.insert(v2);
???????????? }
???????? }//搜索完畢,初始化,便于下次搜索for (int i = 0; i ?< nVerts; i++) {vertexList[i].wasVisited ?= false;
???????? }
???? }public static ?void main(String[] args) {
???????? Graph graph = new Graph();
???????? graph.addVertex('A');
???????? graph.addVertex('B');
???????? graph.addVertex('C');
???????? graph.addVertex('D');
???????? graph.addVertex('E');
???????? graph.addEdge(0,1);???? //ABgraph.addEdge(1,2);???? //BCgraph.addEdge(0,3);???? //ADgraph.addEdge(3,4);???? //DESystem.out.println("廣度優(yōu)先搜索算法:");
???????? graph.breadthFirstSearch();
???? }
?}

總結(jié)

以上是生活随笔為你收集整理的广度优先搜索_计算机入门必备算法——广度优先遍历搜索的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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