堆 在遊戲中的運用
* 定時器的應用與原理:
遊戲中。活動的狀態、遊戲數據的保存與載入、BOSS刷新時間等等,都可能會用到定時器。而堆對於定時器的實現有著至關關鍵的數據。
定時器的工作原理事實上不難,就是內部保存多個時間及其回調函數。當系統時間達到我們保存的時間值時,就運行回調函數。從而達到定時工作的效果。
同一時候,推斷是否達到指定時間時。僅僅須要推斷最早的時間(最早的時間沒有達到,更晚的時間肯定不會達到),因此須要對時間列表進行排序。
起初,我設想定時器內部用於保存時間的數據結構是列表;理由是easy理解、實現簡單。並且刪除節點的時間復雜度為O(1)(對於定時器為說。刪除超時時間,而超時時間肯定是在頭結點。因此時間復雜度為O(1))。
可是這樣的做法有明顯的不足,由於保存時間列表須要排序。因此插入時間節點的時間復雜度為O(n)。
後來。發現堆在定時器有著很好的效率。可是堆排序的時間復雜度為O(nlog2n),“XXX,那不是比列表還慢!”。事實上不然,我們不須要將整個序列都排好序。前面我已經說過“推斷是否達到指定時間時,僅僅須要推斷最早的時間”。也就是說我們僅僅須要知道整個序列的最早時間就可以。
而堆排序剛好有這種一個名詞“小頂堆”。也就是說每次插入時間節點和刪除節點,都將序列維持在小頂堆的狀態就可以。
對於小頂堆,插入節點。又一次調整堆結構。其時間復雜度為O(log2n);刪除節點,又一次調整堆結構,其時間復雜也為O(log2n)。
因此整個用小頂堆實現的定時器的時間復雜也就是O(log2n)。
比起用列表(list)實現的時間復雜度O(n),效率大大提升。
* 小頂堆解說:
堆的保存結構是數組,而堆分為大頂堆和小頂堆,滿足Key[i]>=Key[2i+1]&&key[i]>=key[2i+2]稱為大頂堆,滿足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]稱為小頂堆。
也就是說。大頂堆的每個節點都比子節點大。小頂堆的每個節點都比子節點小。因此由上述性質可知大頂堆的堆頂的keyword肯定是全部keyword中最大的,小頂堆的堆頂的keyword是全部keyword中最小的。
堆是一棵全然二叉樹。以下講述小頂堆在構造。
插入節點:
首先在樹的末端插入新結點,新結點與父結點假設新結點大於等於父結點。則不須要改變;否則交換位置。
刪除堆頂:
刪除堆頂跟刪除節點的原理一樣,而刪除節點跟插入節點剛好相反,刪除的節點向下查找兩個子節點中最小的節點A替換自己的位置,節點A又相當於刪除的節點繼續向下查找。直到葉子節點。
堆 在遊戲中的運用