十字連結串列的AOI演算法
看了雲風寫的AOI演算法文章,自己也照著寫了一下,感覺不容易理解,裡面提到了十字連結串列的演算法,在某同學提示下寫了個實現.
演算法的大概思想如下.每個場景維護兩個連結串列,分別為X軸和Y軸的座標按序排列好的連結串列,也就是比如在X軸連結串列上,越在前的物件,X座標越小,Y軸連結串列同理.這樣,每次需要更新狀態的時候,只需要在這個連結串列上向前或者向後遍歷結點就知道該通知誰了.
這裡假設有三個API:Add(向場景中新增一個物件),Leave(某物件離開場景),Move(某物件在場景中移動).
來一個一個看.
Add:根據新增物件的X,Y座標,依次遍歷X,Y軸座標連結串列,這裡有兩個目的,一個是獲得這個新增物件的座標在X,Y軸座標的位置,另一方面獲得該通知哪些結點.通知的範圍,每個物件可以自己定製自己的通知範圍.但是為了簡單起見,在這裡我們假設每個結點X,Y座標相差1,而通知的範圍是2.比如原有的X軸座標為:
a->b->c->d->e->f->g->h
假設新增一個物件z,它最終所在的位置是c和d之間,根據前面的假設,它只需要通知b,c,e,f四個結點就好了.所以,新增一個結點的時候,並不需要遍歷完連結串列的.
但是這裡還需要注意的是,一個結點,必須X,Y座標同時都在通知範圍內才可以進入通知集合.
Leave:在新增了物件之後,物件身上掛了兩個結點,分別存放在X,Y軸座標連結串列上的位置,那麼在這個物件要離開場景時,也只需要向前向後探索一定的範圍,就可以得到需要通知該物件要離開的集合了.
Move:移動操作比較麻煩,但是也可以比較漂亮的解決.在更新位置之前,同樣根據前面的演算法得到要通知的結點集合,稱為old_set;更新位置之後,再獲取另一個通知集合,稱為new_set;然後,old_set和new_set的交集,稱為move_set,在此集合中的結點,在移動前後都在通知範圍,因此要向這個集合的結點傳送該物件移動的訊息;而old_set-move_set的集合,在移動之後已經離開了視野,因此要向它們傳送該物件離開的訊息;最後,new_set-move_set是移動之後才看見該結點的結點集合,這個集合的結點,要傳送該結點進入場景的訊息.
我把這個演算法的實現放在了這裡.
相關文章
- 用十字連結串列表示的稀疏矩陣類矩陣
- 演算法-連結串列演算法
- 演算法基礎~連結串列~排序連結串列的合併(k條)演算法排序
- 把玩演算法 | 連結串列演算法
- 演算法題中的連結串列演算法
- 【小白學演算法】5.連結串列(linked list)、連結串列的新增演算法
- 結構與演算法(03):單向連結串列和雙向連結串列演算法
- (連結串列)連結串列的排序問題排序
- 資料結構與演算法——連結串列 Linked List(單連結串列、雙向連結串列、單向環形連結串列-Josephu 問題)資料結構演算法
- 演算法面試(一) 連結串列演算法面試
- 初級演算法-連結串列演算法
- 力扣--連結串列演算法力扣演算法
- 筆記--連結串列演算法筆記演算法
- 資料結構學習(C++)——稀疏矩陣(十字連結串列【2】) (轉)資料結構C++矩陣
- 資料結構學習(C++)——稀疏矩陣(十字連結串列【1】) (轉)資料結構C++矩陣
- 連結串列-雙向連結串列
- 連結串列-迴圈連結串列
- 連結串列面試題(二)---連結串列逆序(連結串列反轉)面試題
- javascript中的連結串列結構—雙向連結串列JavaScript
- 演算法 - 連結串列操作思想 && case演算法
- 連結串列4: 迴圈連結串列
- 連結串列-單連結串列實現
- 資料結構與演算法-連結串列資料結構演算法
- 【資料結構與演算法學習】線性表(順序表、單連結串列、雙向連結串列、迴圈連結串列)資料結構演算法
- 連結串列入門與插入連結串列
- 連結串列以及golang介入式連結串列的實現Golang
- Linux核心連結串列-通用連結串列的實現Linux
- 演算法題:反轉一個單連結串列&判斷連結串列是否有環演算法
- [Golang]力扣LeetBook—初級演算法—連結串列—迴文連結串列(快慢指標)Golang力扣演算法指標
- 連結串列
- JavaScript 的資料結構和演算法 - 連結串列篇JavaScript資料結構演算法
- javaScript的資料結構與演算法(二)——連結串列JavaScript資料結構演算法
- 玩轉演算法面試之連結串列演算法面試
- 演算法:排序連結串列:歸併排序演算法排序
- 【演算法詳解】有環連結串列演算法
- Swift 演算法實戰之路:連結串列Swift演算法
- 反轉連結串列、合併連結串列、樹的子結構
- 資料結構與演算法分析——連結串列資料結構演算法