並查集 路徑壓縮 非遞迴寫法
阿新 • • 發佈:2019-01-10
這是樸素查詢的程式碼,適合資料量不大的情況:
int findx(int x) { int r=x; while(parent[r] !=r) r=parent[r]; return r; }
下面是採用路徑壓縮的方法查詢元素:
int find(int x) //查詢x元素所在的集合,回溯時壓縮路徑{ if (x != parent[x]) { parent[x] = find(parent[x]); //回溯時的壓縮路徑 } //從x結點搜尋到祖先結點所經過的結點都指向該祖先結點return parent[x]; }
上面是一採用遞迴的方式壓縮路徑, 但是,遞迴壓縮路徑可能會造成溢位棧,我曾經因為這個RE了n次,下面我們說一下非遞迴方式進行的路徑壓縮:
int find(int x) { int k, j, r; r = x; while(r != parent[r]) //查詢跟節點 r = parent[r]; //找到跟節點,用r記錄下 k = x; while(k != r) //非遞迴路徑壓縮操作 { j = parent[k]; //用j暫存parent[k]的父節點 parent[k] = r; //parent[x]指向跟節點 k = j; //k移到父節點 } return r; //返回根節點的值 }