笛卡爾樹

笛卡爾樹

笛卡爾樹是一種同時滿足二叉搜索樹和堆的性質的數據結構. 可以在一個數組上構造出來(時間複雜度可以達到 O(n) ). 樹中節點有幾個屬性, key(節點元素的大小, 優先級priority), index(節點在元素組中的索引), left(左子節點), right(右子節點), parent(父節點).

性質

  1. 樹中的元素滿足二叉搜索樹性質, 樹的中序遍歷得到的序列爲原數組序列;
  2. 樹中節點滿足堆性質, 節點的==key==值要大於其左右子節點的key值.

構造

要求在給定的數組的基礎上構造一顆笛卡爾樹, 這可以在 O(n) 的時間內完成. 其具體思路爲:

​ 當按照index1n(或者從0n - 1)的順序將數組中的每個元素插入到笛卡爾樹中時, 當前要被插入的元素的index值最大, 因此根據二叉搜索樹的性質, 需要在當前已經完成的笛卡爾樹的根的右子樹中進行搜索.

​ 由於笛卡爾樹要滿足堆的性質(以大根堆爲例), 父節點的key值要大於子節點的key值, 所以沿着樹根的右子樹往下走, 直到遇到的節點的key值小於等於當前要插入節點的key值.

​ 此時, 便找到了當前節點需要插入的位置, 記爲P . 此時P 下方的節點的key值肯定小於當前要插入的節點的key, index也小於當前要插入的節點的index.

​ 所以在講當前節點插入到P的位置後, 把以P爲根的子樹掛到當前已經插入的節點的左子樹上.

​ 實際實現時, 可採用棧. 棧中保存當前樹中從root開始的右子節點鏈, root在棧底.

​ 插入新元素的時候, 從樹的右子鏈的最末尾從下往上查找, 直到找到第一個滿足堆性質的節點(即找到的節點的key值大於當前需要插入的節點). 用棧來實現就是從棧頂不斷彈出元素, 直到棧頂的元素的key大於當前節點的key, 然後將該節點入棧, 同時將最後被彈出的節點的parent指向該節點, 以及該節點的左子節點指向最後彈出的節點.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章