2015-12-06 6 views
6

से धीमी है, मैंने प्रत्येक बार जटिलता की तुलना करने के लिए बाइनरी खोज, रैखिक खोज और एक हैश तालिका लागू की है। समस्या यह है कि किसी भी तरह, मेरी हैश तालिका बाइनरी खोज से बहुत धीमी है जब मैं प्राइम नंबर खोजने के लिए समय मापता हूं।मेरी हैश तालिका द्विआधारी खोज

// Make the hash table 20 times the number of prime numbers 
HashTable::HashTable(std::vector<int> primes) 
{ 
    int tablesize = primes.size() * 20; 
    table = new std::list<int>[tablesize]; 
    size = tablesize; 
    for (auto &prime : primes) 
     this->insert(prime); 
} 

// Hash function 
int HashTable::hash(int key) 
{ 
    return key % size; 
} 

// Finds element 
int HashTable::find(int key) 
{ 
    // Get index from hash 
    int index = hash(key); 

    // Find element 
    std::list<int>::iterator foundelement = std::find(table[index].begin(), table[index].end(), key); 


    // If element has been found return index 
    // If not, return -1 
    if (foundelement != table[index].end()) 
     return index; 
    else 
     return -1; 
} 



// Adds element to hashtable 
void HashTable::insert(int element) 
{ 
    // Get index from hash and insert the element 
    int index = hash(element); 
    table[index].push_back(element); 
} 

HashTable.h

#ifndef HASHTABLE_H 
#define HASHTABLE_H 

#include <list> 
#include <iostream> 
#include <vector> 

class HashTable 
{ 
private: 
    // Each position in Hashtable has an array of lists to store elements in case of collision 
    std::list<int>* table; 

    // Size of hashtable 
    int size; 

    // Hashfunction that returns the array location for the given key 
    int hash(int key); 

public: 

    HashTable(int tablesize); 
    HashTable(std::vector<int> primes); 

    // Adds element to hashtable 
    void insert(int element); 

    // Deletes an element by key 
    void remove(int key); 

    // Returns an element from hashtable for a given key 
    int find(int key); 

    // Displays the hashtable 
    void printTable(); 

    // Display histogram to illustrate elements distribution 
    void printHistogram(); 

    // Returns the number of lists in hash table 
    int getSize(); 

    // Returns the total number of elements in hash table 
    int getNumberOfItems(); 

    // De-allocates all memory used for the Hash Table. 
    ~HashTable(); 
}; 

#endif 

मैं पहले से ही टकराव को खत्म करने के तालिका आकार के आकार को पार करने की कोशिश की है, लेकिन मैं किसी भी अंतर नोटिस नहीं किया: नीचे मेरी कोड है।

This is the result

+4

यह एक बहुत अच्छा ग्राफ है। ऐसा लगता है कि कोई उम्मीद करेगा: हैश खोज में निरंतर समय जटिलता है, और बाइनरी में लॉगरिदमिक है। यह सिर्फ हैश टेबल की स्थिरता काफी बड़ी है। वेक्टर कैश के साथ बहुत अच्छी तरह से खेलते हैं। – PSkocik

+1

बेंचमार्क से शायद असंबंधित; लेकिन कन्स्ट्रक्टर को संदर्भ –

+4

द्वारा 'primes' स्वीकार करना चाहिए यदि आप 'table' के प्रकार को' std :: vector *' में बदलते हैं तो आपके समय का क्या होता है? – msandiford

उत्तर

0

यह जटिलता द्विआधारी खोज के बारे में सब हे (लॉग एन) है, और अपने खोज है, तो हे (एन) रेखीय है एक मुद्दा यह है कि सबसे खराब था जब तुम टकराव का एक बहुत कुछ है पर है।

4

कुछ चीजें हैं जो हैश तालिका कार्यान्वयन के साथ करने से इनकी हैं:

  • primes.size() * 20 अत्यधिक है - आप आवश्यक तुलना में बहुत अधिक कैश छूट जाए मिलेगा; , एक इष्टतम बिंदु

  • primes.size() * 20 भी हमेशा होता है, और सभी रूढ़ अंक आप key % size साथ हैश अजीब हैं खोजने के लिए 1 और 2 के बीच ~ मानों की एक श्रेणी कोशिश ताकि आप कभी आधा बाल्टी में हैश, अंतरिक्ष और अपमानजनक बर्बाद कैश प्रदर्शन

  • आप लिंक की गई सूचियों के साथ टकराव संभालते हैं: इसका मतलब है कि आप हमेशा तालिका की संगत स्मृति से कम से कम एक पॉइंटर का पालन कर रहे हैं, जो धीमा है, और टक्कर के लिए आप सूची में प्रत्येक नोड के साथ स्मृति में चारों ओर कूदते हैं ; कोलाइडिंग मानों को स्टोर करने के लिए std::vector<int> का उपयोग करके हैश टेबल के बाहर 1 मेमोरी एरिया पर कूदना होगा, या आप पास हैश/ओपन एड्रेस और विस्थापन सूचियों का उपयोग कर सकते हैं ताकि आम तौर पर आसपास के हैश टेबल बाल्टी में तत्व ढूंढ सकें: मेरे मानकों ने पाया है कि लगभग समान int मानों के लिए तीव्रता का क्रम तेजी से क्रमबद्ध करें।

1

यदि आपका डेटा पूरी तरह यादृच्छिक है तो मॉड्यूलो ऑपरेशन के लिए एक अच्छा निरंतर खोजना मुश्किल हो सकता है। यदि आपका डेटा किसी प्रकार के पैटर्न का पालन करता है तो आप उम्मीदवार स्थिरांक के समूह के माध्यम से चलने का प्रयास कर सकते हैं यह देखने के लिए कि कौन सा डेटा आपके डेटा पर सबसे अच्छा प्रदर्शन करता है।

this पोस्ट में मैंने दिखाया कि इस प्रकार के बड़े पैमाने पर परीक्षण कैसे संरचित किया जा सकता है। अंत में मेरी हैश तालिका ने 14 तुलनाओं में 1.5 तुलनाओं में औसत लुकअप का उत्पादन किया। तालिका में 16000 प्रविष्टियां थीं, लगभग 2^14।

संबंधित मुद्दे