問題概述:
A task (e.g., A B C …) can be completed during a level only if it has no dependencies or all its dependencies have been have been completed.
A dependency: (A, B) indicates that task A has to be completed before B.
A task list is a list of all tasks to be completed.
A dependency list is a list of all dependencies considered.
顧名思義就是我們要完成一系列任務,單個任務之間可能是依賴關係,比如要完成任務B的前提是完成任務A,每次只能開始能進行的任務。就像完成學校學位所需要完成的課程。
這幅圖很直觀的展現出了要完成CS學位所需要完成的課程以及各個課程之間的依賴關係。
拓撲排序就是通關計算機程序來尋找完成這些任務的順序,還可以延伸到許多不同的問題。
假設B任務必須依賴A才能完成,也就是說B一定在A之後完成,即(A,B)表示B依賴於A。
假設我們有任務A B C D E F G
彼此之間的依賴關係爲(A,B) (C,D) (A,C) (C,E) (E,G) (F,G) (B,E) (D,F)
現在需要計算機程序來輸入這些任務以及依賴關係並計算出可行的完成任務順序來完成所有的這些程序。
根據依賴關係可以做出下面的示意圖。
仔細觀察不難發現每個點或者有幾個箭頭指向它或者沒有,我們可以就此找出每個點有多少個箭頭指向它。
也就是找出每個點的入度,即每個點有多少個依賴點。
其實拓撲排序的思路就是每次遍歷所有點找出入度爲0的點,入度爲0的點也就是當前可以進行的任務點,這些任務點已經不需要任何依賴點就可以直接進行。每當我們找到入度爲0的點並記錄下來後,把該點從當前拓撲關係圖中擦除。再下一次遍歷又會產生新的入度爲0的點,如此往復,一次次的循環,最終如果能把所有的點都擦除,也就表明我們完成了所有任務,而記錄下來的點的順序就是完成任務的順序。
第一次遍歷,我們找到A。
第二次遍歷,我們找到B,C。
第三次遍歷,我們找到D,E。
第四次遍歷,我們找到F。
第五次遍歷,我們找到G。
最終我們發現已經沒有點存在了,那麼我們已經完成了所有的任務,而這五次遍歷找到的點在一起的順序就是我們要找到完成所有任務的順序。因爲我們進行了五次遍歷完成了所有的任務,那麼完成這些任務的最少級數就是5。
下一篇來分析,怎麼設計數據結構在程序裏面實現任務管理系統。