1. 程式人生 > >笛卡爾樹(Cartesian Tree)

笛卡爾樹(Cartesian Tree)

  笛卡爾樹是一棵二叉樹,樹的每個節點有兩個值,一個為index,一個為value。光看index的話,笛卡爾樹是一棵二叉搜尋樹,每個節點的左子樹的index都比它小,右子樹都比它大;光看value的話,笛卡爾樹有點類似堆,根節點的value是最小(或者最大)的,每個節點的value都比它的子樹要小(或者大)。
  它可以處理範圍最值查詢、範圍top k查詢(range top k queries)等問題。
  
  如圖就是一棵笛卡爾樹(上方表格中每個數的編號為index,數值為value,下方是根據資料生成的笛卡爾樹):
  笛卡爾樹
  直接構造的方法是排序以後再插入,這樣就需要O(n

log2n)O(n2)的時間複雜度,而這花費的時間太多,因此我們要尋找一種更加便捷的方式處理:
  我們注意到這個樹C的右鏈,即根結點、根結點的右兒子、根結點的右兒子的右兒子……組成的鏈,它們的index和value都是遞增的,所以如果插入一個新的數a[i],比a[i]大的數都不會在右鏈中,在新樹中會出現在a[i]的左子樹裡。根據這個原理,我們就可以設計一個棧來儲存右鏈,每增加一個數從頂部處理一次即可。