多級樹的深度優(yōu)先遍歷與廣度優(yōu)先遍歷(Java實(shí)現(xiàn))

多級樹的深度優(yōu)先遍歷與廣度優(yōu)先遍歷(Java實(shí)現(xiàn))

深度優(yōu)先遍歷與廣度優(yōu)先遍歷其實(shí)是屬于圖算法的一種,多級樹可以看做是一種特殊的圖骚揍,所以多級數(shù)的深/廣遍歷直接套用圖結(jié)構(gòu)的遍歷方法即可。

工程中后端通常會用多級樹來存儲頁面表單的各級聯(lián)動類目跨嘉,本文提供了深度遍歷與廣度遍歷的示例抗悍,在使用時只要根據(jù)你的業(yè)務(wù)需求稍加改動即可。

我們知道脸狸,遍歷有遞歸最仑,非遞歸兩種方式。在工程項目上肥惭,一般是禁用遞歸方式的盯仪,因?yàn)檫f歸非常容易使得系統(tǒng)爆棧。同時蜜葱,JVM也限制了最大遞歸數(shù)量全景,在你的樹結(jié)構(gòu)非常深的時候很容易出現(xiàn)StackOverflowError異常,所以最好采用非遞歸的方式牵囤。

節(jié)點(diǎn)模型

public class Node {
    //值
    public int value;
    //所有的子節(jié)點(diǎn)
    public ArrayList<Node> nexts;

    public Node(int value) {
        this.value = value;
    }
}

深度優(yōu)先遍歷

深度優(yōu)先搜索英文縮寫為DFS即Depth First Search.其過程簡要來說是對每一個可能的分支路徑深入到不能再深入為止爸黄,而且每個節(jié)點(diǎn)只能訪問一次。多級樹可以看做一個特殊的圖結(jié)構(gòu)揭鳞,總的來說遍歷的方法還是不變的炕贵,都是利用棧和Set來進(jìn)行操作。

主要步驟:

  1. 準(zhǔn)備一個棧結(jié)構(gòu)和一個Set結(jié)構(gòu)的集合野崇,棧用來記錄還有孩子沒有被遍歷到的節(jié)點(diǎn)称开,Set用來記錄遍歷的歷史記錄
  2. 將首節(jié)點(diǎn)加入到棧和set中
  3. 彈棧拿到首節(jié)點(diǎn)
  4. 從首節(jié)點(diǎn)開始深度遍歷,下面示例代碼配合注解近進(jìn)行理解。
public static void dfs(Node node) {
    if (node == null) {
        return;
    }
    Stack<Node> stack = new Stack<>();
    HashSet<Node> set = new HashSet<>();
    stack.add(node);
    set.add(node);
    System.out.println(node.value);
    
    while (!stack.isEmpty()) {
        //彈棧獲得一個節(jié)點(diǎn)
        Node cur = stack.pop();
        //查看這個節(jié)點(diǎn)的所有孩子
        for (Node next : cur.nexts) {
            //如果有孩子是之前沒有遍歷到的鳖轰,說明這個節(jié)點(diǎn)沒有深度遍歷完
            if (!set.contains(next)) {
                //此節(jié)點(diǎn)與其孩子加入棧與Set中
                stack.push(cur);
                stack.push(next);
                set.add(next);
                System.out.println(next.value);
                break;
            }
        }
    }
}

廣度優(yōu)先遍歷

寬度優(yōu)先搜索算法(又稱廣度優(yōu)先搜索)是最簡便的圖的搜索算法之一清酥,這一算法也是很多重要的圖的算法的原型。對于多級數(shù)來說蕴侣,就是先遍歷該節(jié)點(diǎn)的所有孩子焰轻,然后在遍歷孩子節(jié)點(diǎn)的所有孩子,先遍歷一層再遍歷下一次層昆雀。

主要思路就是利用隊列來將下一層的所有節(jié)點(diǎn)記錄下來辱志,然后順序遍歷就可以了。

public static void bfs(Node node) {
    if (node == null) {
        return;
    }
    Queue<Node> queue = new LinkedList<>();
    //用來注冊已加入隊列的節(jié)點(diǎn)——>防止重復(fù)添加節(jié)點(diǎn)
    HashSet<Node> set = new HashSet<>();
    queue.add(node);
    set.add(node);
    while (!queue.isEmpty()) {
        Node cur = queue.poll();
        System.out.println(cur.value);
        //將節(jié)點(diǎn)的所有下游節(jié)點(diǎn)加入到隊列
        for (Node next : cur.nexts) {
            if (!set.contains(next)) {
                set.add(next);
                queue.add(next);
            }
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末狞膘,一起剝皮案震驚了整個濱河市揩懒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌客冈,老刑警劉巖旭从,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異场仲,居然都是意外死亡和悦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門渠缕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸽素,“玉大人,你說我怎么就攤上這事亦鳞♀珊觯” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵燕差,是天一觀的道長遭笋。 經(jīng)常有香客問我,道長徒探,這世上最難降的妖魔是什么瓦呼? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮测暗,結(jié)果婚禮上央串,老公的妹妹穿的比我還像新娘。我一直安慰自己碗啄,他們只是感情好质和,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著稚字,像睡著了一般饲宿。 火紅的嫁衣襯著肌膚如雪厦酬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天瘫想,我揣著相機(jī)與錄音弃锐,去河邊找鬼。 笑死殿托,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的剧蚣。 我是一名探鬼主播支竹,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鸠按!你這毒婦竟也來了礼搁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤目尖,失蹤者是張志新(化名)和其女友劉穎馒吴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瑟曲,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饮戳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了洞拨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扯罐。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖烦衣,靈堂內(nèi)的尸體忽然破棺而出歹河,到底是詐尸還是另有隱情,我是刑警寧澤花吟,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布秸歧,位于F島的核電站,受9級特大地震影響衅澈,放射性物質(zhì)發(fā)生泄漏键菱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一矾麻、第九天 我趴在偏房一處隱蔽的房頂上張望纱耻。 院中可真熱鬧,春花似錦险耀、人聲如沸弄喘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蘑志。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間急但,已是汗流浹背澎媒。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留波桩,地道東北人戒努。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像镐躲,于是被迫代替她去往敵國和親储玫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345