天天看點

算法:二叉搜尋樹與雙向連結清單

算法:二叉搜尋樹與雙向連結清單

輸入一棵二叉搜尋樹,将該二叉搜尋樹轉換成一個排序的循環雙向連結清單。要求不能建立任何新的節點,隻能調整樹中節點指針的指向。

為了讓您更好地了解問題,以下面的二叉搜尋樹為例:

算法:二叉搜尋樹與雙向連結清單

我們希望将這個二叉搜尋樹轉化為雙向循環連結清單。連結清單中的每個節點都有一個前驅和後繼指針。對于雙向循環連結清單,第一個節點的前驅是最後一個節點,最後一個節點的後繼是第一個節點。

下圖展示了上面的二叉搜尋樹轉化成的連結清單。“head” 表示指向連結清單中有最小元素的節點。

算法:二叉搜尋樹與雙向連結清單

特别地,我們希望可以就地完成轉換操作。當轉化完成以後,樹中節點的左指針需要指向前驅,樹中節點的右指針需要指向後繼。還需要傳回連結清單中的第一個節點的指針。

方法:中序周遊

算法解析:

  • 初始化兩個節點,分别 pre(前驅節點)、head(頭節點);
  • 如果 root 節點為空,直接傳回;
  • 遞歸中序周遊轉化為雙向連結清單:
    • 如果目前節點為空,直接傳回;
    • 按照中序周遊的規則,遞歸左子樹;
    • 如果前驅節點為空,說明是頭節點,頭節點即為目前節點;目前驅節點非空,修改雙向節點的引用,前驅節點的右子節點指向目前節點;目前節點的左子節點指向前驅節點;
    • 更新前驅節點等于目前節點,這樣目前節點時下一個節點的前驅節點了;
    • 按照中序周遊的規則,遞歸右子樹。
  • 遞歸完畢後,把頭節點的左子節點指向前驅節點;前驅節點的右子節點指向頭節點;
  • 傳回連結清單的頭節點。

代碼如下:

算法:二叉搜尋樹與雙向連結清單

複雜度分析

  • 時間複雜度:O(N),N 為二叉樹的節點數,中序周遊需要通路所有節點。
  • 空間複雜度:O(N),最差情況下,即樹退化為連結清單時,遞歸深度達到 N,系統使用 O(N) 棧空間。

END

書山有路勤為徑,學海無涯苦作舟,贈友人。

好兄弟可以點贊并關注我的公衆号“javaAnswer”,全部都是幹貨。

繼續閱讀