問題描述:給出點及點間的關系,指定點為根節點,把有向圖轉化為樹。其中,有向圖中的環,只是兩個節點之間。比如
經過去掉環得到
其中圖的表示為:
1->2 2->4 2->5 1->3 5->2
解決之道
先用字典node_dic把整個圖表示出來;列表has_kid存放不是葉子的節點;列表node_list是個隊列,存放本節點和它的孩子;列表have_exist表示已經存在的節點,對於node_list如果不是孩子節點,又不在have_exist中,當被遍歷是存於have_exist,同時在node_lst刪除該節點。之后遍歷node_list,如果之前已經存在於have_exist中了,則刪除之間的關系。剩下的部分為無環圖。
示例
node_dic: {1:[2, 3], 2:[4, 5], 5:[2]}
has_kid: [1, 2, 5]
指定根節點為1
步驟
*)一開始node_list存放根節點:(注意node_list背景色為紅色,have_eist為綠色)
此時:node_dic: {1:[2, 3], 2:[4, 5], 5:[2]}
**)看node_list的第一個節點,不在have_exist,又不是孩子節點,把它所有的孩子存於隊列node_list,查看孩子是否在have_exist,要是在就刪除node_dic中的關系。最后刪除首節點
***)看node_list的第一個節點,不在have_exist,又不是孩子節點,把它所有的孩子存於隊列node_list,查看孩子是否在have_exist,要是在就刪除node_dic中的同時刪除首節點。
****)看node_list的第一個節點4、5,是孩子節點,直接刪除該節點
此時:node_dic: {1:[2, 3], 2:[4, 5], 5:[2]}
*****)看node_list的第一個節點,在have_exist,刪除首節點,同時刪除node_dice中的關系。
參考代碼(python)
node_relation = ['1->2', '2->4', '2->5', '5->2', '1->3'] root = '1' node_dic = {} have_kid = [] have_exist = [] node_list = [] for key in node_relation: chunk = key.split("->") if not chunk[0] in have_kid: have_kid.append(chunk[0]) if not node_dic.has_key(chunk[0]): node_dic[chunk[0]] = [] node_dic[chunk[0]].append(chunk[1]) else: node_dic[chunk[0]].append(chunk[1]) node_list.append(root) while len(node_list) != 0: rmtmp = [] if not node_list[0] in have_kid: node_list.remove(node_list[0]) else: for key in node_dic[node_list[0]]: node_list.append(key) if key in have_exist: rmtmp.append(key) if node_list[0] not in have_exist: have_exist.append(node_list[0]) for keyy in rmtmp: node_dic[node_list[0]].remove(keyy) node_list.remove(node_list[0]) print node_dic
結果:{'1': ['2', '3'], '2': ['4'], '5': []}