我們要解決兩個問題:
1.如何將所有二維矩形塊
放入乙個矩形框內。
2.在滿足問題1的情況下,矩形框的最小寬度和高度是多少。
期望的效果圖:
下面我們就來解決以上問題。
1. 把矩形塊放在固定大小的框內
假設有乙個固定大小的矩形框,比如1024x768,我們怎麼把矩形塊裝在裡面?答案:使用二叉樹
。首先在左上角放置第乙個(最大的)塊,然後將該矩形框剩餘的空白區域分割成兩個較小的矩形
以二叉樹的形式遞迴地進行處理,最後得到乙個填充的影象
程式實現非常簡單。假設輸入矩形
塊已經按從大到小排序。
packer = function(w, h) ;
};packer.prototype =
},findnode: function(root, w, h) ,
splitnode: function(node, w, h) ;
node.right = ;
return node;
}}
2.
選擇最小寬度和高度
我們現在可以使用一棵二叉樹來將矩形塊放入乙個固定大小的矩形。但是我們應該選擇多大的尺寸來確保所有的矩形塊都能以最優的方式放置
我考慮了很多啟發式方法。其中乙個例子是取平均寬度和平均高度,然後分別乘以sqrt(n),以生成乙個正方形。n是矩形塊的數量。因為使用了平均值,生成矩形塊矩形框可能太大也可能太小。
那麼有沒有別的方法呢?下面來看我們提出的方法。
3. 將矩形塊填充進乙個不斷增長的矩形框
我們不是試圖猜測矩形框的最優寬度和高度,我們可以先建立乙個小的目標:能容下第乙個矩形塊。
然後在沒有足夠的空間來容納下乙個塊的時候,擴充矩形框。
先來看下沒有足夠的空間來容納下一矩形塊的情況:
這時我們有兩種選擇,我們可以讓矩形框向下生長,或者向右生長
這可以通過在原始程式中新增幾行**來實現:
fit: function(blocks) ;
for (n = 0; n < blocks.length; n++)
},
實際上,實現grownode方法時需要一些條件判斷:
grownode: function(w, h) ,
幾點注意事項:
這對演算法有相當大的影響。如果乙個塊比矩形框的寬和高都大,那麼我們就不能生長了!解決方案是確保我們的塊首先被排序,這樣所有後續的塊都至少有乙個邊緣比矩形框小。
這並不是說我們不能支援這個
,但會新增額外的複雜性。
這就阻止了我們不斷地向右生長並建立乙個水平的長條。這也阻止了我們不斷的向下生長並創造乙個狹窄的垂直地帶。它的結果近似於正方形。
4.對矩形塊排序
塊被放入框的順序對結果有很大的影響。讓我們先看看專家們怎麼說:
理論和實證結果表明,『first fit decreasing』是最好的啟發式方法。按照從大到小的順序排列物件,這樣最大的物件第一放入,最小的最後乙個放。將每個物件依次地插入到第乙個有空間可以容納它的箱子裡。
這裡的大小是什麼意思?寬度?高度?面積嗎?
通過從各種排序演算法中進行選擇:寬度
高度面積
maxside——(寬度,高度)
隨機-隨機化順序
每一種主要排序也有二級(有時是第**)排序標準,以避免在其他情況下是相等的。
結果表明,maxside幾乎總是最好的選擇。
意思是,結果大致是正方形的(不是長而細的),並且有最少的空白。
二叉樹之 二叉樹深度
二叉樹深度 獲取最大深度 public static int getmaxdepth treenode root 二叉樹寬度 使用佇列,層次遍歷二叉樹。在上一層遍歷完成後,下一層的所有節點已經放到佇列中,此時佇列中的元素個數就是下一層的寬度。以此類推,依次遍歷下一層即可求出二叉樹的最大寬度 獲取最大...
二叉樹(二)之二叉查詢樹
目錄 一 二叉查詢樹的概念 二 二叉查詢樹的實現 三 二叉查詢樹 binary search tree 又被稱為二叉搜尋樹。它是特殊的二叉樹 對於二叉樹,假設x為二叉樹中的任意乙個結點,x節點包含關鍵字key,節點x的key值記為key x 如果y是x的左子樹中的乙個結點,則key y key x ...
演算法基礎之二叉樹
本文主要包括樹相關的演算法,二叉樹結點基本結構如下 function treenode x 本文還會繼續更新。function depth proot var depth 0 var currdepth 0 dfs proot return depth function dfs node currd...