一、什麼是深度優先遍歷
深度優先遍歷演算法是經典的圖論演算法。從某個節點v出發開始進行搜索。不斷搜索直到該節點所有的邊都被遍歷完,當節點v所有的邊都被遍歷完以後,深度優先遍歷演算法則需要回溯到v以前驅節點來繼續搜索這個節點。
注意:深度優先遍歷問題一定要按照規則嘗試所有的可能才行。
二、二叉樹
2.二叉樹類型
二叉樹類型:空二叉樹、滿二叉樹、完全二叉樹、完美二叉樹、平衡二叉樹。
空二叉樹:有零個節點
完美二叉樹:每一層節點都是滿的二叉樹(如1中舉例的圖)
滿二叉樹:每一個節點都有零個或者兩個子節點
完全二叉樹:出最後一層外,每一層節點都是滿的,並且最後一層節點全毀行歷部從左排列
平衡二叉樹:每個節點的兩個子樹的深度相差不超過1.
註:國內對完美二叉樹和滿二叉樹定義相同
3.二叉樹相關術語
術語 解釋
度 節點的度為節點的子樹個數
葉子節點 度為零的節點
分支節點 度不為零的節點
孩子節點 節點下的兩個子節點
雙親節點 節點上一層的源節點
兄弟節點 擁有同一雙親節點的節點
根 二叉樹的源頭節點
深度 二叉樹中節點的層的數量
DLR(先序):
LDR(中序):
LRD(後序):
注意:L代表左子樹R代表右子樹;D代表根
6.深度優先遍歷和廣度優先遍歷
深度優先遍歷:前序、中序和後序都是深度優先遍歷
從根節點出發直奔最遠節點,
廣度優先遍歷:首先訪問舉例根節點最近的節纖搜點,按層次遞進,以廣度優先遍歷上圖的順序為:1-2-3-4-5-6-7
三、面試題+勵志
企鵝運維面試題:帶局
1.二叉樹遍歷順序:看上文
2.用你熟悉的語言說說怎麼創建二叉樹? python看上文
❷ 一篇文章告訴你python爬蟲原理,知其然更知其所以然,從此爬蟲無憂
Python,一種面向對象、直譯式電腦編程語言,功能強大且通用性強,已有近二十年的發展歷史,其標准庫完善且易懂,能輕松完成多種任務。Python支持多種編程範式,如命令式、面向對象、函數式、面向切面、泛型編程,並具有垃圾回收功能,自動管理存儲器使用。它常用於處理系統管理和網路編程,也可執行復雜任務。Python虛擬機幾乎能在所有作業系統中運行,通過工具如py2exe、PyPy、PyInstaller可將Python源代碼轉換為可獨立運行的程序。
爬蟲教程通常會從頁面提取數據、介紹HTTP協議、講解模擬登錄和反爬蟲策略,最後提供簡單Scrapy教程。這些教程往往忽略了爬蟲的核心邏輯抽象,即如何遍歷網頁。實際上,只需要使用兩個隊列和一個集合,即可實現基礎通用爬蟲。
互聯網由頁面構成,頁面間由鏈接連接,形成有向圖結構。可以使用廣度優先或深度優先演算法遍歷此圖。雖然圖巨大,但我們僅關注感興趣的節點,如某個域名下的網頁。廣度優先和深度優先可用遞歸或隊列實現。但使用Python寫爬蟲時,不能使用遞歸,因為調用棧深度限制,可能導致異常。因此,推薦使用隊列實現網頁遍歷。
理論知識後,以爬取煎蛋網的妹子圖為例,說明如何獲取上下頁鏈接。需避免重復訪問已訪問頁面,使用集合存儲已訪問頁面。從頁面中抽取所需數據,如圖片,可以使用xpath表達式。將運行請求和運行項目放入不同線程,實現同時遍歷網頁和下載圖片。
最終實現煎蛋妹子圖爬蟲,所有爬蟲框架本質上相似,Scrapy採用類似方式,但使用Lifo Queue實現深度優先遍歷。通過配置文件,可實現爬取目標數據,簡化代碼修改。遇到封鎖時,可採用靈活策略應對,如使用pipeline。
Python適用於多個領域,如web開發、自動化運維、大數據分析、科學計算、機器學習和人工智慧。從零基礎到專業領域,Python均具有廣泛應用。通過不同需求和專業背景,掌握Python可實現多種功能。
❸ 常見演算法5、廣度優先搜索 Breadth-First Search
1、定義
廣度優先搜索 (Breadth-First Search)是最簡便的圖的搜索演算法之一,又稱 寬度優先搜索 ,這一演算法也是很多重要的圖演算法的原型。廣度優先搜索屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位置,徹底地搜索整張圖,直到找到結果為止。
2、應用
廣度優先搜索被用於解決 最短路徑問題(shortest-path problem) 。
廣度優先搜索讓你能夠找出兩樣東西之間的最短距離,不過最短距離的含義有很多!使用廣度優先搜索可以:
3、圖簡介
既然廣度優先搜索是作用於圖的一種演算法,這里對圖作一個簡單的介紹,先不深入了解。
圖由 節點 和 邊 組成。一個節點可能與多個節點相連,這些節點被稱為鄰居。
廣度優先演算法的核心思想是:從初始節點開始,應用算符生成第一層節點,檢查目標節點是否在這些後繼節點中,若沒有,再用產生式規則將所有第一層的節點逐一擴展,得到第二層節點,並逐一檢查第二層節點中是否包含目標節點。若沒有,再用算符逐一擴展第二層的所有節點……,如此依次擴展,檢查下去,直到發現目標節點為止。即
廣度優先搜索使用隊列(queue)來實現,整個過程也可以看做一個倒立的樹形。
例:假如你需要在你的人際關系網中尋找是否有職業為醫生的人,圖如下:
而使用廣度優先搜索工作原理大概如下 :
1、Python 3 :
2、php :
1、《演算法圖解》 https://www.manning.com/books/grokking-algorithms
2、SplQueue類: https://www.php.net/manual/zh/class.splqueue.php
❹ 有向圖和無向圖的有關知識
有/無 向圖如果給圖的每條邊規定一個方向,那麼得到的圖稱為有向圖,其邊也稱為有向邊。在有向圖中,與一個節點相關聯的邊有出邊和入邊之分,而與一個有向邊關聯的兩個點也有始點和終點之分。相反,邊沒有方向的圖稱為無向圖。[編輯]簡單圖一個圖如果沒有兩條邊,它們所關聯的兩個點都相同(在有向圖中,沒有兩條邊的起點終點都分別相同);每條邊所關聯的是兩個不同的頂點則稱為簡單圖(simple graph)。簡單的有向圖和無向圖都可以使用以上的「二元組的定義」,但形如(x,x)的序對不能屬於E。而無向圖的邊集必須是對稱的,即如果 ,那麼 。[編輯]多重圖若允許兩結點間的邊數多於一條,又允許頂點通過同一條邊和自己關聯,則為多重圖的概念。它只能用「三元組的定義」。[編輯]基本術語在頂點1有一個環階(Order):圖G中頂集V的大小稱作圖G的階。子圖(Sub-Graph):圖G'稱作圖G的子圖如果以及 。生成子圖(Spanning Sub-Graph):指滿足條件V(G') =V(G)的G的子圖G。度(Degree)是一個頂點的度是指與該頂點相關聯的總邊數,頂點v的度記作d(v)。度和邊有如下關系:。出度(out-degree) 和入度 (in-degree):對有向圖而言,頂點的度還可分為出度和入度。一個頂點的出度為 do ,是指有 do 條邊以該頂點為起點,或說與該點關聯的出邊共有do條。入度的概念也類似。鄰接矩陣環(loop):若一條邊的兩個頂點相同,則此邊稱作環。路徑(path):從頂點 u 到頂點 v 的一條路徑是指一個序列v0,e1,v1,e2,v2,...ek,vk, ei的起點終點為vi及vi - 1; k 稱作路徑的長度; v_0=u,稱為路徑的起點; v_k=v,稱為路徑的終點。如果 u=v,稱該路徑是閉的,反之則稱為開的;如果 v_1 , ... , v_k 兩兩不等,則稱之為簡單路徑(simple path)(注意,u=v 是允許的)。行跡(trace):如果路徑P(u,v)中邊各不相同,則該路徑稱為u到v的一條行跡。軌道(track):即簡單路徑。閉的行跡稱作迴路(circuit),閉的軌道稱作圈(Cycle)。(現存文獻中的命名法並無統一標准。比如在另一種定義中,walk 對應上述的 path,path 對應上述的 track , trail 對應上述的 trace。)距離(distance): 從頂點 u 出發到頂點 v 的最短路徑若存在,則此路徑的長度稱作從 u 到 v 的距離。若從 u 到 v 根本不存在路徑,則記該距離為無窮(∞)。距離矩陣橋(bridge):若去掉一條邊,便會使得整個圖不連通,該邊稱為橋。[編輯]圖的存儲表示數組(鄰接矩陣)存儲表示(有向或無向)鄰接表存儲表示前向星存儲表示有向圖的十字鏈表存儲表示無向圖的鄰接多重表存儲表示一個不帶權圖中若兩點不相鄰,鄰接矩陣相應位置為0,對帶權圖(網),相應位置為∞。一個圖的鄰接矩陣表示是唯一的,但其鄰接表表示不唯一。在鄰接表中,對圖中每個頂點建立一個單鏈表(並按建立的次序編號),第i個單鏈表中的結點表示依附於頂點vi的邊(對於有向圖是以頂點vi為尾的弧)。每個結點由兩個域組成:鄰接點域(adjvex),用以指示與vi鄰接的點在圖中的位置,鏈域(nextarc)用以指向依附於頂點vi的下一條邊所對應的結點。如果用鄰接表存放網(帶權圖)的信息,則還需要在結點中增加一個存放權值的域(info)。每個頂點的單鏈表中結點的個數即為該頂點的出度(與該頂點連接的邊的總數)。無論是存儲圖或網,都需要在每個單鏈表前設一表頭結點,這些表頭結點的第一個域data用於存放結點vi的編號i,第二個域firstarc用於指向鏈表中第一個結點。[編輯]圖的遍歷圖的遍歷方法有深度優先搜索法和廣度(寬度)優先搜索法。深度優先搜索法是樹的先根遍歷的推廣,它的基本思想是:從圖G的某個頂點v0出發,訪問v0,然後選擇一個與v0相鄰且沒被訪問過的頂點vi訪問,再從vi出發選擇一個與vi相鄰且未被訪問的頂點vj進行訪問,依次繼續。如果當前被訪問過的頂點的所有鄰接頂點都已被訪問,則退回到已被訪問的頂點序列中最後一個擁有未被訪問的相鄰頂點的頂點w,從w出發按同樣的方法向前遍歷,直到圖中所有頂點都被訪問。其遞歸演算法如下:Boolean visited[MAX_VERTEX_NUM]; //訪問標志數組Status (*VisitFunc)(int v); //VisitFunc是訪問函數,對圖的每個頂點調用該函數void DFSTraverse (Graph G, Status(*Visit)(int v)){ VisitFunc = Visit; for(v=0; v<G.vexnum; ++v) visited[v] = FALSE; //訪問標志數組初始化 for(v=0; v<G.vexnum; ++v) if(!visited[v]) DFS(G, v); //對尚未訪問的頂點調用DFS}void DFS(Graph G, int v){ //從第v個頂點出發遞歸地深度優先遍歷圖Gvisited[v]=TRUE; VisitFunc(v); //訪問第v個頂點for(w=FirstAdjVex(G,v); w>=0; w=NextAdjVex(G,v,w))//FirstAdjVex返回v的第一個鄰接頂點,若頂點在G中沒有鄰接頂點,則返回空(0),//若w是v的鄰接頂點,NextAdjVex返回v的(相對於w的)下一個鄰接頂點。//若w是v的最後一個鄰接點,則返回空(0)。 if(!visited[w]) DFS(G, w); //對v的尚未訪問的鄰接頂點w調用DFS}圖的廣度優先搜索是樹的按層次遍歷的推廣,它的基本思想是:首先訪問初始點vi,並將其標記為已訪問過,接著訪問vi的所有未被訪問過的鄰接點vi1,vi2, …, vi t,並均標記已訪問過,然後再按照vi1,vi2, …, vi t的次序,訪問每一個頂點的所有未被訪問過的鄰接點,並均標記為已訪問過,依次類推,直到圖中所有和初始點vi有路徑相通的頂點都被訪問過為止。其非遞歸演算法如下:Boolean visited[MAX_VERTEX_NUM]; //訪問標志數組Status (*VisitFunc)(int v); //VisitFunc是訪問函數,對圖的每個頂點調用該函數void BFSTraverse (Graph G, Status(*Visit)(int v)){ VisitFunc = Visit;for(v=0; v<G.vexnum, ++v) visited[v] = FALSE; initQueue(Q); //置空輔助隊列Q for(v=0; v<G.vexnum; ++v) if(!visited[v]){ visited[v]=TRUE; VisitFunc(v); EnQueue(Q, v); //v入隊列 while(!QueueEmpty(Q)){ DeQueue(Q, u); //隊頭元素出隊並置為u for(w=FirstAdjVex(G,u); w>=0; w=NextAdjVex(G,u,w)) if(!Visited[w]){ //w為u的尚未訪問的鄰接頂點 Visited[w]=TRUE; VisitFunc(w); EnQueue(Q, w); } } }}
[編輯]圖的重要類型樹平面圖連通圖強連通圖有向無環圖AOV網AOE網完全圖:每一對不同頂點間都有邊相連的的圖,記作Kn。二分圖:頂集,且每一條邊都有一個頂點在X中,而另一個頂點在Y中。完全二分圖:二分圖G中若任意兩個X和Y中的頂點都有邊相連。若,則圖G記作Km,n。正則圖:如果圖中所有頂點的度皆相等,則此圖稱為正則圖歐拉圖:存在經過所有邊一次(可以多次經過點)的路徑的圖哈密頓圖:存在經過所有點一次的路徑的圖
❺ 找最短路徑的方法
1),深度或廣度優先搜索演算法(解決單源最短路徑)
從起始結點開始訪問所有的深度遍歷路徑或廣度優先路徑,則到達終點結點的路徑有多條,取其中路徑權值最短的一條則為最短路徑。
給定一個帶權有向圖G=(V,E),其中每條邊的權是一個實數。另外,還給定V中的一個頂點,稱為
源。
現在要計算從源到其他所有各頂點的最短路徑長度。這里的長度就是指路上各邊權之和。這個問題通
常稱為單源最短路徑 問題。
從起始結點開始訪問所有的深度遍歷路徑或廣度優先路徑,則到達終點結點的路徑有多條,取其中路
徑權值最短的一條則為最短路徑
❻ python 演算法種類
python雖然具備很多高級模塊,也是自帶電池的編程語言,但是要想做一個合格的程序員,基本的演算法還是需要掌握,本文主要介紹列表的一些排序演算法
遞歸是演算法中一個比較核心的概念,有三個特點,1 調用自身 2 具有結束條件 3 代碼規模逐漸減少