[演算法] [C++ / Python] 深度優先搜尋Depth-First-Search - Part I

文章推薦指數: 80 %
投票人數:10人

更新:熱騰騰的Part II 出爐囉! 深度優先搜尋,Depth-First-Search,簡稱DFS,是一種用於圖或樹的遍歷、搜尋演算法。

樹. 我們先畫一棵樹如下:. 跳到主要內容 [演算法][C++/Python]深度優先搜尋Depth-First-Search-PartI 取得連結 Facebook Twitter Pinterest 以電子郵件傳送 其他應用程式 6月17,2017 更新:熱騰騰的PartII出爐囉! 深度優先搜尋,Depth-First-Search,簡稱DFS,是一種用於圖或樹的遍歷、搜尋演算法。

樹 我們先畫一棵樹如下:  是不是很繽紛呢(X畫完樹之後,我們要選一個「起點」,在這裡我們選紅色的 1。

接下來我們可以看到,有三個節點與1相連,分別是  2 ,  3 ,  4 。

 接下來就是DFS的精華:先選一個節點「深」入研究,於是在這裡我們先選2來進行下一步。

選2之後呢?我們會把  2  當作新的起點,再做一次DFS,因此我們找到了  5 。

 糟了,以5為起點的話就找不到任何的節點了,這樣就結束了嗎?當然不是,這種情況下我們要返回到上一個節點,也就是2,看看有沒有還沒去過的節點。

 --也沒有,我們只好再回到1,有了!剛剛先被我們放到一邊的3和4,於是我們選擇  3  作為我們新DFS的起點。

啊糟糕,原來3下面也沒有其他節點了XD   我們只好回到1,去尋求4的幫助(?),我們以  4  為起點進行DFS,發現有 6 跟  7  兩個節點;依據DFS的原則,先訪問其中一個,在這裡選6,接著回到4,再走到7。

 因為7後面沒有節點了,所以回到4,再回到1,結果發現1也沒了,因此,DFS到此全部完畢。

程式碼實作-C++ voiddfs(Node*start){ if(start==nullptr){//如果這個位置沒有節點 return;//返回上一個 } cout<data<next[i]);//分別以目前所找到的節點作為下一次DFS的起點 } } 這裡僅列出重點部分,完整程式碼請至這裡查看 程式碼實作-Python defdfs(start): ifstartisNone:#如果這個位置沒有節點 return#返回上一個 print(start.data,'visited.') foriinrange(3): dfs(start.next[i])#分別以目前所找到的節點作為下一次DFS的起點 這裡一樣只列出重點部分,完整程式碼請至這裡查看 程式設計-演算法-搜尋-樹、圖 程式設計-Cpp 程式設計-Python 取得連結 Facebook Twitter Pinterest 以電子郵件傳送 其他應用程式 留言 這個網誌中的熱門文章 [C]每天來點字串用法(2)-strcpy()、strncpy() 2月11,2018 結果隔了四天(不要相信blogger自帶的時間(?))才更新qwq,前幾天根本忘得一乾二淨XD進入正文吧,今天要介紹的是:strcpy()、strncpy():字串複製 所屬標頭檔: 函式宣告:char*strcpy(char*dest,constchar*src);char*strncpy(char*dest,constchar*src,size_tcount); 先說strcpy(),將來源字串(src)複製到目的地(dest),並回傳dest指向的字串,要注意的有以下兩點:     1)第一個參數是目的地(dest),第二個是來源(src)     2)會有緩衝區溢位(bufferoverflow) 的問題 來看看何謂緩衝區溢位:假設有一程式進行了如下宣告:inti=5;chars[8]="Hi1234"; 那麼這些變數的記憶體配置可能如下: 如果今天我們進行了如下操作:strcpy(s,"hellosky"); 那麼記憶體裡的內容就會變成如下: 於是這時i的值就會變成121,我們可以用以下程式來驗證:#include#includeintmain(void){inti=5;chars[8]="Hi1234";printf("addressofi:%p\naddressofs:%p\n",&i,s);//i:0028ff1c,s:0028ff14strcpy(s,"hellosky");printf("valueofs:%s\nvalueofi:%d\n",s,i);//s:hellosky,:121return0;} 為了解決這樣的問題,我們可以改用strncp 繼續閱讀 [Python]*args和**kwargs是什麼?一次搞懂它們! 4月30,2018 在翻閱Python的函式庫時常常會看到定義參數的地方放了*args和**kwargs這樣的東西,這究竟是什麼呢?讓我們先談談函式參數的定義。

預設參數 一般的定義方法就不多說了,直接來看有預設值的參數:defplus(a,b,c=None):res=a+b+(cifcelse0)returnres 預設參數的用處通常是實作函式重載用的,可以使一個函式在接受引數時更有彈性,而要注意的語法問題是:預設參數在函式定義時一定要放在非預設參數的後面。

 但如果我們想實作無限版的plus()函式呢?總不可能一直增加預設參數吧! 這時候我們可以用「*」來將引數收集到一個tuple中。

*-收集至Tuple 先來看看範例:defplus(*nums):res=0foriinnums:res+=ireturnres 透過*收集的引數會被放到一個tuple中,所以我們可以使用for來對它進行迭代。

 這樣就可以理解為什麼要使用*args這個參數了,但是**kwargs又是什麼呢?我們要先從關鍵字引數來說起:關鍵字引數KeywordArgument 在呼叫print()時,我們有時會指定sep參數做為分隔輸出的字元,或是使用end參數來更改最後的換行字元。

像這樣不用理會參數的真正順序,而只要給定名字然後指定值的情況,就是在使用關鍵字引數。

 如果我們要指定的參數太多而造成版面不簡潔的話,可以考慮使用「**」來拆解一個裝有參數名與值的dict。

**第一招-拆解Dict 原諒我使用這麼中二的小標題XDD 直接看實例應該就能懂了:dt={'sep':'#','end':'\n\n'}print('hello','world',**dt)#等同於print('hello','world',sep='#',end=& 繼續閱讀 [C]每天來點字串用法(5)-strcat()、strncat() 2月24,2018 好的,不知道又過了幾天(廢),終於要來到第5篇了。

strcat()、strncat():串接字串 所屬標頭檔: 函式宣告:char*strcat(char*dest,constchar*src);char*strncat(char*dest,constchar*src,size_tcount); 看到這熟悉的命名,該不會跟strcpy()、strncpy()那組函式很像吧?沒錯,所以按照上次的慣例,我們先來看看strcat()。

 strcat()有兩個參數,分別是dest和src,而這個函式的功用是將src接到dest後面,再回傳dest指向的字串。

那你可能會問:那原本dest的'\0'字元會跑去哪呢?答案是會被src的第一個字元(也就是src[0])所取代,並在最後面補上一個'\0'來當做新字串的結束字元。

 看到名字多了一個n的函式,你可能會猜,是不是這個strcat()也會造成緩衝區溢位的問題呢?沒錯,所以接下來要介紹比較推薦的函式:strncat()。

 如果有看過之前那一篇的話,應該都已經知道這個函式要怎麼用了,他會多接受一個整數,作為控制最多串接的字元數。

不過這裡的機制跟strcpy()有點不一樣:     1)無論如何都會在最後放一個'\0',而這個'\0'並不受count的限制。

也就是說,真正串接字元數的最大值其實是count +1。

 讓我們來看看他們的使用範例:#include#includeintmain(){//strcatchars1[8]="hi",s2[8]="sky";strcat(s1,s2);printf("%s\n\n",s1);//strncatchars3[8],s4[8];scanf("%s%s&q 繼續閱讀 天ほし 瀏覽簡介 分類 日常-短談3 日常-預告1 程式設計-天天來一點小技巧7 程式設計-資料庫-SQL-sqlite4 程式設計-演算法-搜尋-樹、圖3 程式設計-C-字串7 程式設計-C#-好用類別1 程式設計-Cpp5 程式設計-Lua6 程式設計-Python9 歌詞翻譯-日文2 顯示更多 顯示較少 網誌存檔 2021 1 三月 1 2020 1 一月 1 2019 7 九月 1 七月 3 五月 3 2018 15 九月 1 七月 2 五月 1 四月 2 三月 2 二月 7 2017 4 六月 2 [演算法][C++/Python]深度優先搜尋Depth-First-Search-P... [C#]ZipFile類別的使用 二月 1 一月 1 2016 4 十二月 4 顯示更多 顯示較少 檢舉濫用情形



請為這篇文章評分?