我有一個包含我的節點的ArrayList。節點具有源,目標和成本。現在我必須迭代整個ArrayList。這持續了超過1000個節點。因此我嘗試按來源對我的List進行排序。但是爲了在列表中找到相應的對,我嘗試了二進制搜索。不幸的是,只有當我想比較源或目標時纔有效。但我必須比較兩者才能找到合適的配對。是否有另一種可能性來搜索ArrayList高效?數據結構中的高效搜索ArrayList
回答
不幸的是,沒有。 ArrayList
不能被有效搜索。它們用於存儲數據而不搜索它。如果您只想知道是否包含某個項目,我建議您使用HashSet
,因爲查找將具有O(1)的時間複雜度而不是ArrayList的O(n)(假定您已實施了功能equals
方法爲你的對象)。
如果您想快速搜索對象,我推薦使用Dictionnary
的實現,如HashMap
。如果您可以承擔空間要求,則可以擁有多個地圖,每個地圖都有不同的密鑰,以便快速查找對象,而無論您需要搜索哪個密鑰。請記住,查找還需要實施正確的方法。不幸的是,這要求每把鑰匙都是獨一無二的,在你的情況下這可能不是一個好主意。
但是,您可以使用HashMap
來爲每個源存儲以鍵控源作爲源的節點列表。您可以爲成本和目標做同樣的事情。這樣可以減少大量迭代所需的節點數量。這應該證明對於幾乎沒有連接的網絡來說是一個很好的解決方案。
private HashMap<Source, ArrayList<Node>> sourceMap = new HashMap<Source, ArrayList<Node>>();
private HashMap<Target, ArrayList<Node>> targetMap = new HashMap<Target, ArrayList<Node>>();
private HashMap<Cost, ArrayList<Node>> costMap = new HashMap<Cost, ArrayList<Node>>();
/** Look for a node with a given source */
for(Node node : sourceMap.get(keySource))
{
/** Test the node for equality with a given node. Equals method below */
if(node.equals(nodeYouAreLookingFor) { return node; }
}
爲了確保您的代碼將工作,一定要覆蓋equals
方法。我知道我已經這麼說了,但這是一個非常普遍的錯誤。
@Override
public boolean equals(Object object)
{
if(object instanceof Node)
{
Node node = (Node) object;
if(source.equals(node.getSource() && target.equals(node.getTarget()))
{
return true;
}
} else {
return false;
}
}
如果不這樣做,測試將簡單地比較可能相同或不相等的參考,具體取決於您如何處理對象。
編輯:只讀你基於你的平等。 equals方法應該在你的節點類中實現。但是,要使其工作,您需要實現並重寫源和目標的equals方法。也就是說,如果它們是物體。不過要注意的是,如果它們也是Node
,這可能會導致跨所有網絡的相當多的測試。
更新:添加代碼以反映代碼在評論中的用途。
ArrayList<Node> matchingNodes = sourceMap.get(desiredSourde).retainAll(targetMap.get(desiredTarget));
現在您有一個與源和目標條件匹配的所有節點的列表。假設你願意犧牲一點內存,上面的查找將會具有O(| sourceMap | *(| sourceMap | + | targetMap |))的複雜度[1]。雖然這優於僅僅對所有節點進行線性查找O(| allNodeList |),但如果您的網絡足夠大,我認爲它具有1000個節點,那麼您可以從中受益匪淺。如果你的網絡遵循一個自然發生的網絡,那麼就像Albert-LászlóBarabási所表明的那樣,它可能沒有規模。這意味着將網絡分成至少源和目標列表可能(我沒有證據證明這一點)導致這些列表的無尺度分佈。因此,我相信查找源代碼和目標代碼的複雜度將大大降低爲| sourceMap |和| targetMap |應該大大低於| allNodeList |。
這實際上並不是我想要的。我現在創建了一個Map
由於錯誤轉貼評論! \t 是的,但你必須搜索的集合大大減少。我會建議的是,您按照我注意到的方式嘗試它,然後執行以下操作:獲取源數爲3的所有節點的集合,獲取目標爲8的所有節點,獲取兩個集合的交集。然後您將擁有一個集合,其中包含源爲3,目標爲8的所有節點。對於交集,請查看Java的retainAll(List)方法。如果你願意,我可以提供一個例子! – Eric
僅供參考,截至Java 7,您不再需要冗餘,冗餘'HashMap
您需要將源和目標合併爲一個比較器,例如,
compare(T o1, T o2) {
if(o1.source < o2.source) { return -1; }
else if(o1.source > o2.source) { return 1; }
// else o1.source == o2.source
else if(o1.target < o2.target) { return -1; }
else if(o1.target > o2.target) { return 1; }
else return 0;
}
您可以使用.compareTo()
方法來比較您的節點。
我試着用compareTo(),但我需要確保源和目標與我正在比較的節點相同。因此用compareTo()不可能做到這一點。 –
您可以創建兩個ArrayList。第一個按來源排序,第二個按目標排序。 然後,您可以使用相應List上的binarySearch按源或目標進行搜索。
你可以讓一個輔助類來存儲源 - 目標對:
class SourceTarget {
public final Source source; // public fields are OK when they're final and immutable.
public final Target target; // you can use getters but I'm lazy
// (don't give this object setters. Map keys should ideally be immutable)
public SourceTarget(Source s, Target t){
source = s;
target = t;
}
@Override
public boolean equals(Object other){
// Implement in the obvious way (only equal when both source and target are equal
}
@Override
public int hashCode(){
// Implement consistently with equals
}
}
然後你的東西存放在HashMap<SourceTarget, List<Node>>
,與映射到放有這個源 - 節點列表中的每個源 - 目標對目標對。 只獲得使用
List<Node> results = map.get(new SourceTarget(node.source, node.target));
或者以製作一個輔助類,你可以使用以星 - 讚的答案比較,並充當SourceTarget
對有代表性的Node
對象TreeMap<Node,List<Node>>
。
- 1. 用於高效多參數搜索的數據結構
- 2. 用於高效插入和搜索的Javascript數據結構
- 3. 快速高效搜索的數據結構
- 4. 數據結構排序+搜索有效
- 5. 高效的數據結構
- 6. 高效的數據結構
- 7. 高效的數據結構
- 8. Maple中的高效數據結構
- 9. 搜索三數據結構
- 10. Drupal數據庫結構 - 高效/低效?
- 11. 搜索中的重要數據結構
- 12. 高效的數據庫搜索LIKE'%something%'
- 13. Trie數據結構和Java中的有效搜索
- 14. 快速隨機訪問,搜索,插入和刪除的高效數據結構
- 15. 高效的MongoDB數據庫結構
- 16. 高效的列表數據結構
- 17. 排行榜的高效數據結構
- 18. 最高效的Java數據結構
- 19. 高效的MySQL數據庫結構
- 20. Zobrist鍵的高效數據結構
- 21. 是否有索引結構(數據結構)或算法可以高效快速地執行鄰近搜索?
- 22. ArrayList的數據結構
- 23. 高維最近鄰搜索的最佳數據結構
- 24. 高效的java數據結構來刪除和檢索信息?
- 25. deleteMin和按鍵操作搜索的有效數據結構
- 26. 高效搜索FORTRAN中的數組
- 27. Firebase - 爲高效索引構造數據
- 28. Clojure的數據結構遍歷/搜索
- 29. 面向搜索的數據庫結構
- 30. 搜索引擎的數據結構?
你如何做搜索?你必須匹配這兩個對的項目?或者您需要能夠搜索僅匹配每對中的一個項目的記錄? – Plato
我在我提供的答案中添加了一些代碼。我希望它會證明有用! – Eric
數據來自哪裏?您在1000個節點中使用的數據,您從哪裏獲取數據? – LuckyMe