日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

四叉树和八叉树

發(fā)布時間:2024/9/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 四叉树和八叉树 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前序

四叉樹或四元樹也被稱為Q樹(Q-Tree)。四叉樹廣泛應(yīng)用于圖像處理、空間數(shù)據(jù)索引、2D中的快速碰撞檢測、存儲稀疏數(shù)據(jù)等,而八叉樹(Octree)主要應(yīng)用于3D圖形處理。對游戲編程,這會很有用。本文著重于對四叉樹與八叉樹的原理與結(jié)構(gòu)的介紹,幫助您在腦海中建立四叉樹與八叉樹的基本思想。本文并不對這兩種數(shù)據(jù)結(jié)構(gòu)同時進行詳解,而只對四叉樹進行詳解,因為八叉樹的建立可由四叉樹的建立推得。若有不足之處,望能不吝指出,以改進之。^_^ ?歡迎Email:zhanxinhang@gmail.com

四叉樹與八叉樹的結(jié)構(gòu)與原理

四叉樹(Q-Tree)是一種樹形數(shù)據(jù)結(jié)構(gòu)。四叉樹的定義是:它的每個節(jié)點下至多可以有四個子節(jié)點,通常把一部分二維空間細分為四個象限或區(qū)域并把該區(qū)域里的相關(guān)信息存入到四叉樹節(jié)點中。這個區(qū)域可以是正方形、矩形或是任意形狀。以下為四叉樹的二維空間結(jié)構(gòu)(左)和存儲結(jié)構(gòu)(右)示意圖(注意節(jié)點顏色與網(wǎng)格邊框顏色):

?

四叉樹的每一個節(jié)點代表一個矩形區(qū)域(如上圖黑色的根節(jié)點代表最外圍黑色邊框的矩形區(qū)域),每一個矩形區(qū)域又可劃分為四個小矩形區(qū)域,這四個小矩形區(qū)域作為四個子節(jié)點所代表的矩形區(qū)域。

較之四叉樹,八叉樹將場景從二維空間延伸到了三維空間。八叉樹(Octree)的定義是:若不為空樹的話,樹中任一節(jié)點的子節(jié)點恰好只會有八個,或零個,也就是子節(jié)點不會有0與8以外的數(shù)目。那么,這要用來做什么?想象一個立方體,我們最少可以切成多少個相同等分的小立方體?答案就是8個如下八叉樹的結(jié)構(gòu)示意圖所示:

?

?

四叉樹存儲結(jié)構(gòu)的c語言描述:

[cpp]?view plaincopy
  • /*?一個矩形區(qū)域的象限劃分::?
  • ???????????
  • ???????UL(1)???|????UR(0)?
  • ?????----------|-----------?
  • ???????LL(2)???|????LR(3)?
  • 以下對該象限類型的枚舉?
  • */??
  • typedef?enum??
  • {??
  • ????UR?=?0,??
  • ????UL?=?1,??
  • ????LL?=?2,??
  • ????LR?=?3??
  • }QuadrantEnum;??
  • ??
  • /*?矩形結(jié)構(gòu)?*/??
  • typedef?struct?quadrect_t??
  • {??????
  • ????double??left,???
  • ????????????top,???
  • ????????????right,???
  • ????????????bottom;??
  • }quadrect_t;??
  • ??
  • /*?四叉樹節(jié)點類型結(jié)構(gòu)?*/??
  • typedef?struct?quadnode_t??
  • {??
  • ????quadrect_t????rect;??????????//節(jié)點所代表的矩形區(qū)域??
  • ????list_t????????*lst_object;???//節(jié)點數(shù)據(jù),?節(jié)點類型一般為鏈表,可存儲多個對象??
  • ????struct??quadnode_t??*sub[4];?//指向節(jié)點的四個孩子???
  • }quadnode_t;??
  • ??
  • /*?四叉樹類型結(jié)構(gòu)?*/??
  • typedef?struct?quadtree_t??
  • {??
  • ????quadnode_t??*root;??
  • ????int?????????depth;???????????//?四叉樹的深度??????????????????????
  • }quadtree_t;??


  • 四叉樹的建立

    1、利用四叉樹分網(wǎng)格,如本文的第一張圖<四層完全四叉樹結(jié)構(gòu)示意圖>,根據(jù)左圖的網(wǎng)格圖形建立如右圖所示的完全四叉樹。

    偽碼:

    Funtion QuadTreeBuild ( depth, rect )

    ? ?{

    QuadTree->depth = depth;


    /*創(chuàng)建分支,root樹的根,depth深度,rect根節(jié)點代表的矩形區(qū)域*/

    QuadCreateBranch ( ?root, depth, rect );

    ? ?}


    Funtion QuadCreateBranch ( n, depth,rect )

    ? ?{

    if ( depth!=0 )

    ? ?{

    n = new node; ? ?//開辟新節(jié)點

    n ->rect = rect; //將該節(jié)點所代表的矩形區(qū)域存儲到該節(jié)點中

    將rect劃成四份 rect[UR], rect[UL], rect[LL], rect[LR];


    /*創(chuàng)建各孩子分支*/

    QuadCreateBranch ( n->sub[UR], depth-1, rect [UR] );

    QuadCreateBranch ( n->sub[UL], depth-1, rect [UL] );

    QuadCreateBranch ( n->sub[LL], depth-1, rect [LL] );

    QuadCreateBranch ( n->sub[LR], depth-1, rect [LR] );

    ? ?}

    ? ?}


    2、假設(shè)在一個矩形區(qū)域里有N個對象,如下左圖一個黑點代表一個對象,每個對象的坐標位置都是已知的,用四叉樹的一個節(jié)點存儲一個對象,構(gòu)建成如下右圖所示的四叉樹。


    方法也是采用遞歸的方法對該矩形進行劃分分區(qū)塊,分完后再往里分,直到每一個子矩形區(qū)域里只包含一個對象為止。

    偽碼:

    Funtion QuadtreeBuild()

    ? {

    ???? Quadtree = {empty};
    ? ? ?For (i = 1;i<n;i++) ? ? ?//遍歷所有對象

    {

    ? ?QuadInsert(i, root);//將i對象插入四叉樹

    }? ? ? ? ??

    ? ? ? ? ?剔除多余的節(jié)點; ? ? ? //執(zhí)行完上面循環(huán)后,四叉樹中可能有數(shù)據(jù)為空的葉子節(jié)點需要剔除
    ? }????


    Funtion QuadInsert(i,n) ? ? ?//該函數(shù)插入后四叉樹中的每個節(jié)點所存儲的對象數(shù)量不是1就是0

    ? {??

    ?????if(節(jié)點n有孩子)

    ?{??????

    ? ? 通過劃分區(qū)域判斷i應(yīng)該放置于n節(jié)點的哪一個孩子節(jié)點c;???????

    ? ? QuadInsert(i,c);

    ?}

    ???? else if(節(jié)點n存儲了一個對象)

    ?{

    ? ? 為n節(jié)點創(chuàng)建四個孩子;

    ? ? 將n節(jié)點中的對象移到它應(yīng)該放置的孩子節(jié)點中;

    ? ? 通過劃分區(qū)域判斷i應(yīng)該放置于n節(jié)點的哪一個孩子節(jié)點c;

    ? ? QuadInsert(i,c);

    ?}

    ???? else if(n節(jié)點數(shù)據(jù)為空) ? ?

    ?{

    ? ? 將i存儲到節(jié)點n中;

    ?}

    ? }?


    (以上兩種建立方法作為舉一反三之用)


    用四叉樹查找某一對象

    1、采用盲目搜索,與二叉樹的遞歸遍歷類似,可采用后序遍歷或前序遍歷或中序遍歷對其進行搜索某一對象,時間復雜度為O(n)。

    ?

    2、根據(jù)對象在區(qū)域里的位置來搜索,采用分而治之思想,時間復雜度只與四叉樹的深度有關(guān)。比起盲目搜索,這種搜索在區(qū)域里的對象越多時效果越明顯


    偽碼:

    Funtion?find ( n, pos, )

    ? {

    ? ? ? If (n節(jié)點所存的對象位置為 pos所指的位置 )

    ? ? ? ? ? Return?n;

    ? ? ? If ( pos位于第一象限 )

    ? ? ? ? ? temp = find ( n->sub[UR], pos );

    ? ? ? else if ( pos位于第二象限)

    ? ? ? ? ? temp = find ( n->sub[UL], pos );

    ? ? ? else if ( pos位于第三象限 )

    ? ? ? ? ? temp = find ( n->sub[LL], pos );

    ? ? ? else ?//pos 位于第四象限

    ? ? ? ? ? temp = find ( n->sub[LR], pos );

    ? ? ? return temp;???

    ? }?

    結(jié)語:

    熟話說:結(jié)構(gòu)之法,算法之道。多一種數(shù)據(jù)結(jié)構(gòu)就多一種解決問題的方法,多一種方法就多一種思維模式。祝君學習愉快!^_^

    ?==============================================

    聲明:版權(quán)所有,轉(zhuǎn)載請注明出處:?http://blog.csdn.net/zhanxinhang/article/details/6706217

    參考:維基百科、百度百科

    參考:CS267: Lecture 24, Apr 11 1996?Fast Hierarchical Methods for the N-body Problem, Part 1


    總結(jié)

    以上是生活随笔為你收集整理的四叉树和八叉树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。