TopoSort 實現之不用高階靜態鏈棧演算法

2021-09-30 12:14:58 字數 2354 閱讀 2794

和fawks大神**之後,理解了大神的思維方式,收穫不少。感覺當年ds學的靜態鏈棧實在坑爹,而且麻煩,好像和我的本質沒有太大的區別哦。時間複雜度o(n+e)其實和o(n^2)是鄰接矩陣和臨界表的區別。

我的理解就是其實好像迴圈n次,。思路非常簡單,但是coding實現還是有很多變化,我已開始不用indegree,直接matrix寫了

乙個o(n^3)的,就是不斷在matrix上折騰,用了indegree陣列之後,可以降到o(n^2)。這裡需要注意的是,用什麼樣的ds可以時間複雜度盡可能小,如使用array,那麼需要找值為0的數n次,同時還要找到這個點指向的幾個點集,

然後對應indegree分量減一,看似sort,其實不需要,因為只需要找為0的,不需要後面的都有序,如果最小的如果不為0就不能toposort了,用sort會複雜度從內層o(n)到o(nlogn)上。好像heap可以o(logn),但是heap會打亂順序,使得從matrix上找對應點在indegree上的index變得麻煩,因為還要高效的

隨機訪問 graph[top][j]==true, j的indegree--,所以還是陣列方便,遍歷一遍,indgree--的同時,再找=0的。

**的演算法過程中遇到乙個bug,就是內層迴圈找graph[top][j]==true的,但是後面top又可能立馬被賦值,使得每次找的未必是乙個點的臨界點,我看**愣是沒看出來,debug才得知,而且new的陣列檢視變數值又蛋疼。

所以感覺bug都出在左值上,以後檢視奇怪的bug都去看左值,頂住迴圈的左值,一般迴圈都容易出問題,因為會不斷操作。

**風格上,感謝fawks大神給出的建議,變數用了全域性確實很簡單,不用new來new去,不用擔心忘delete。然後還要判斷bool值不用完整判斷語句。

同時在**過程中熟悉了下二維陣列傳遞的問題,new的陣列可以用bool**,棧的陣列用bool a[b] 不能bool* a這種,而且不能bool a這也必須制定第二維長度,一直費解,後來從二維的最終實現上理解了,二維a[i][j] 本質是a[i*n+j] 這個是編譯器做的事情,本質是一維連續陣列,而n正是第二維長度,試想不知道n編譯器怎麼定位資料,第一維無所謂,編譯器才不管你越不越界勒。所以到了更高位也可以根據這個知道那幾位必須制定了,例如三維陣列,看成很多 第一維表示第幾個  所以a[i][j][k]=i*(d2*d3)+j*d3+k,因此必須指定d2 d3的維度,d1可以忽略,總結好像只有第一維可以忽略,不論多少維的。

附上fawks大神查閱後修改過**風格的**:

#include using namespace std;

const int maxnum=10000;

bool graph[maxnum][maxnum];

int indegree[maxnum];

void toposort(int n)

} toposort(graph, indegree, n);

/*delete indegree;

for(int i=0;i最後其實有一點總結,就是一定要請思考。因為原來ds學的後來看看很費解,還要一遍一遍手動模擬。其實自己想想,就是乙個array,但是和書本的殊途同歸。然後看書本的就好多了,這也印證了張一博大神」**只有作者和上帝知道在幹嘛「的說法

後來看到別處可以用dfs實現ts,而且教材ppt上也是這麼說dfs重要性的,於是乎dfs搞搞ts,有乙個問題,如果遞迴進去,發現找不到度為0,也即不存在ts時,可能需要另外輸出count或者什麼的來判斷是否無ts,因為中間是不好print no ts的。之前也是先建立indegree,中間遍歷的」剪枝「也是一樣判斷indegree,同樣用-1表示已經print

void dfs(int i, int n)

{ cout<

和曹旻老師討論後,有了更透徹的理解。如果用鄰接表的話,是有區別的,

靜態鏈棧只要訪問剛才print的點對應的邊鍊錶,

因為top記錄了當前indegree為0鏈結成的乙個靜態鏈,

如果用鄰接矩陣的話,則是遍歷n個頂點,

所以和用普通的陣列實現是差不多的。

但其實時間複雜度在用鄰接矩陣的時候有降低,陣列還是o(n^2), 因為遍歷陣列找0,靜態戀戰 o(n+e) 因為是訪問頂點的linklist (注:原來的說法:「只是說常數因子減少了,

就好比多個頂點對的最短路徑用floyd而不用n次dijstr

a一樣。」是有誤的,我後來想清楚了)但是matrix 兩者都一樣的。

另外乙個陣列兩用是說如果要用  把入度為0的點鏈結起來的方式   實現,比單獨再開乙個棧要節省空間

今天看到曹博的***pt裡寫dp演算法過程是拓撲排序,很有意思,感覺是對dp演算法的理解

順便補上乙個超讚,精簡的典型基於ds的演算法,附上

用棧來模擬出拓撲的先後關係,**看得讓人爽到爆!

ps:**要gcc編譯器,某軟的編譯器不認識陣列長度未知的陣列定義,即使是在類的成員函式裡!

拓撲排序的實現 TopoSort

拓撲排序是求乙個aov網 頂點代表活動,各條邊表示活動之間的率先關係的有向圖 中各活動的乙個拓撲序列的運算,可用於測試aov 網路的可行性.整個演算法包含三步 1.計算每乙個頂點的入度,存入indegree陣列中.2.檢查indegree陣列中頂點的入度,將入度為零的頂點進棧.3.不斷從棧中彈出入度...

a b等於幾(不用 )高階解法

給出兩個整數a和b,求他們的和,但不能使用 等數 算符。說明a和b都是 32位 整數麼?是的我可以使用位運算子麼?當然可以 樣例如果 a 1 並且 b 2,返回3 目錄 實驗解析 函式說明 結果展示附錄 簡單方法確實想著簡單,但是做起來還是分類挺多的,我們再來 一下更簡便的方法 不相同初級解法 二進...

不用 實現加法運算

寫乙個函式,求兩個整數之和,要求在函式體內不得使用 四則運算符號。示例 輸入 a 1,b 1 輸出 2a,b 均可能是負數或 0 結果不會溢位 32 位整數 我覺得寫這個題一定要對原反補碼的機制非常熟悉,其實加減乘除本身就是我們人自己的思維,在硬體底層笨豬cpu是沒有這麼複雜的想法的,首先cpu只有...