將一個二叉樹轉化為雙向鏈表,不開辟新空間


假設 轉后后 節點 的 left 指針 作為 next 指針, right 指針 作為 prev 指針

思路:首先可以利用的指針 即是 葉子節點 的 指針。這樣 我們 可以 不斷  把 一部分節點 移到 找到的新葉子節點 后面,比如 把 右節點 移到 左葉子幾點后面。

簡單的想, 假設 我們 把 左右子樹已經 轉換 好了, 這個時候 我們 我們 只要 把 右子樹轉換后的鏈表 添加 到 左子樹 的鏈表 后,將 左子樹的 right 指針 指向 根節點。根節點的right指針指向空。

 

先來 三個 節點

1 空節點 (NULL節點) :  返回空

2 只有根節點:直接返回

3 有個左孩子: 父節點 left 指針 指向 下一個節點 即 左孩子 ,不變

                             right 指針 保持 為空 (注意 不是 循環鏈表,所以 prev 指針 不用指向 尾節點 ), 即 父節點 保持 不變

                    左孩子 的 right 指針 指向 父節點 ,left 指針 指向空 不變

4 有個右孩子: 父節點 沒有 左孩子,所以 右子樹 鏈表 可以直接 加到 父節點下面 。所以 父節點 的 left 指針 指向 右孩子。right 指針 改為 指向 空

                    右孩子 沒有 下一個節點了,所以 left 指針 為空 不變, 由於前面有父節點,所以 right 指針 指向 父節點

5 左右孩子:先轉換 左子樹,得到 一個雙向鏈表 ,只有一個節點即左孩子,再轉換 右節點 同理。

                第二步 將 右子樹 的 鏈表 加到 左子樹 的 后面,所以 左孩子的 left 指針 指向 右孩子,右孩子的 right 指針 指向 根節點的左孩子。

                第三步 根節點 作為 左孩子的前一個節點 也就是 整個鏈表的首節點,right 指針指向空,左孩子的 right 指向 根節點。

 為了 在 轉換 左子樹 后 ,將 右子樹 加到 左子樹形成的鏈表的后面,轉換 函數 返回 鏈表的 最后一個 節點

python 代碼:

class BTree(object):

    def __init__(self,v,left=None,right=None):
        self.value = v
        self.left = left
        self.right = right

    def toDLink(self):
        def _(node):
            'move right node to left leaf'
            assert node != None
            if node.left == None and node.right == None: # only self, like S2
                return node
            if node.left == None: # only right , like s4
                tail = _(node.right) # change right tree
                node.right.right = node # right child's prev pointer point to father node
                node.left = node.right # father node's next pointer point to right node
                node.right = None # father prev pointer point to null
            elif node.right == None: # only left , like s3
                tail = _(node.left) # change left tree            
                node.left.right = node # left child prev pointer
            else: # both , like s5
                ltail = _(node.left)
                rtail = _(node.right)
                node.right.right = ltail
                ltail.left = node.right
                node.right = None
                node.left.right = node
                tail = rtail
            return tail
        _(self)

  

 變形題: 一顆有序二叉樹,轉換為 一個 有序 雙向鏈表 (2014校招研發筆試

 思路 一樣, 只是 不將 右子樹 形成 的 鏈表 加到 左子樹形成的鏈表后 面 罷了。反過來 將 根節點 和 左子樹形成的鏈表 加到 右子樹形成的鏈表后面 ,然后 鏈表頭結點不再一定是根節點,要保存頭結點,當然也可以從尾節點回溯過去得到,只是一個正反序的問題。

 

總的來說 還是 二叉樹的 前序,中序 或 后序 遍歷。

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM