2012-04-06 19 views
7

के लिए कुशल डेटा संरचना मैं डेटा संरचना (सरणी जैसी) की तलाश में हूं जो तेजी से (ओ (एन) से तेज) संरचना में मूल्यों के मनमाने ढंग से सम्मिलन की अनुमति देता है। डेटा संरचना को डालने के तरीके में अपने तत्वों को प्रिंट करने में सक्षम होना चाहिए। यह List.Insert() (जो बहुत धीमा है क्योंकि इसे हर तत्व को स्थानांतरित करना है) के समान है, सिवाय इसके कि मुझे यादृच्छिक पहुंच या हटाने की आवश्यकता नहीं है। सम्मिलन हमेशा 'सरणी' के आकार के भीतर होगा। सभी मूल्य अद्वितीय हैं। कोई अन्य परिचालन की आवश्यकता नहीं है।सम्मिलन

उदाहरण के लिए, यदि सम्मिलित करें (x, i) इंडेक्स i (0-अनुक्रमणिका) पर मान x डालता है। तब:

  • सम्मिलित (1, 0) {1}
  • सम्मिलित देता है (3, 1) देता है {1,3}
  • सम्मिलित (2, 1) देता है {1,2,3}
  • सम्मिलित (5, 0) {5,1,2,3}

देता है और यह अंत में बाहर {5,1,2,3} मुद्रित करने के लिए सक्षम होने के लिए की आवश्यकता होगी।

मैं सी ++ का उपयोग कर रहा हूं।

+0

"सरणी" जैसे आपका क्या मतलब है? – juanchopanza

+0

क्या आपके पास डेटा संरचना को पार करने की जटिलता के बारे में आवश्यकताएं हैं? –

+0

@juanchopanza मेरा मतलब सतह पर है, इसे एक रैखिक सरणी की तरह कार्य करना चाहिए। इसे तत्वों को उस तरीके से रखना चाहिए जिसमें मैंने उन्हें डाला है। – Peter

उत्तर

9

skip list का उपयोग करें। एक और विकल्प tiered vector होना चाहिए। स्किप सूची कॉन्स्ट ओ (लॉग (एन)) पर आवेषण करती है और संख्याओं को क्रम में रखती है। टायर वेक्टर O (sqrt (n)) में डालने का समर्थन करता है और फिर क्रम में तत्वों को प्रिंट कर सकता है।

संपादित करें:

प्रत्येक तत्व आप अगले तत्वों के लिए और प्रत्येक के लिए लिंक पर एक टावर है के लिए लिंक आप जानते हैं: अमित की टिप्पणी प्रति मैं कैसे आप एक को छोड़ सूची का k- वां तत्व मिल रहा है समझा जाएगा यह कितने तत्व कूदता है। तो सूची के शीर्ष के साथ शुरू होने वाले के-वें तत्व की तलाश करें और टावर को तब तक नीचे जाएं जब तक आपको एक ऐसा लिंक न मिल जाए जो कि के तत्वों पर आगे नहीं बढ़ता। आप इस नोड द्वारा इंगित नोड पर जाते हैं और आपके द्वारा जंप किए गए तत्वों की संख्या के साथ k को कम करते हैं। जारी कर कि आप k = 0.

+1

मैं स्किप-लिस्ट की लाइनों पर भी विचार कर रहा था, क्या आप कृपया बता सकते हैं कि आप कैसे पहुंच-लिंक्ड सूचियों को संशोधित करते हैं [वे जो मनमाने ढंग से स्थान में तत्व डालने के बाद 'ओ (लॉगन)' खोज] की गारंटी देते हैं? क्या उनमें से बहुत से बदलाव की आवश्यकता नहीं होगी? मेरा मानना ​​है कि [स्किप-लिस्ट] को यहां फिट करने के लिए संशोधित किया जा सकता है, लेकिन इस बिंदु को विस्तारित किया जाना चाहिए आईएमओ – amit

+0

वास्तव में जिस तरह से मैंने कुछ समय पहले स्किप सूची लागू की है, आपने कभी नोड की ऊंचाई को कभी नहीं बदला है।यह इस तथ्य पर निर्भर करता है कि यदि आप समान रूप से वितरित ऊंचाई के साथ प्रत्येक नए नोड को सम्मिलित करते हैं तो तत्वों की ऊंचाई सही लोगों के लिए पर्याप्त होगी। इस दृष्टिकोण की अमूर्त जटिलता पर इंटरनेट पर कुछ विश्लेषण हुए थे जो दिखाते हैं कि यह सबसे अच्छा संभव नहीं है। –

+0

जो मुझे समझ में नहीं आता है वह ऊंचाई को संशोधित करने का तरीका नहीं है, लेकिन सूचकांक, आप तत्व को कैसे बता सकते हैं? यदि आपकी "चाबियां" इंडेक्स हैं, तो क्या प्रत्येक मनमाने ढंग से प्रविष्टि को लिंक की गई सूची की पूरी पूंछ बदलने की आवश्यकता नहीं होगी? [यह ऊंचाई नहीं है जो मुझे चिंता करती है, गैर-निर्धारिती लिंक्ड सूची का उपयोग करके इस मुद्दे को अच्छी तरह से हल करता है] – amit

1

क्या आपने std::map या std::vector का उपयोग करने पर विचार किया था?

आप std::map का उपयोग कुंजी के रूप में सम्मिलन के रैंक के साथ कर सकते हैं। और vector में reserve सदस्य फ़ंक्शन है।

+1

ओपी तेज़ी से रैखिक मनमानी डालने की इच्छा रखता है, क्या वेक्टर और मानचित्र दोनों ओ (एन) नहीं होंगे? – amit

+0

हां, 'i'' स्थिति के लिए 'std :: vector' सम्मिलन ओ (' n') होगा क्योंकि 'i'' के माध्यम से तत्वों को स्थानांतरित करने की आवश्यकता है। 'Std :: map' के साथ, कुछ ऐसा ही होता है क्योंकि कुंजी को अद्यतन करना होता है। –

+0

@Yavar: लेकिन आपको प्रत्येक सम्मिलन के बाद निम्नलिखित सभी तत्वों के सूचकांक को संशोधित करना होगा। मान लें कि आपके पास नक्शा = [(1, ए), (2, बी), (3, सी)] है और आप स्थान 0 में जेड जोड़ना चाहते हैं, तो आपको मानचित्र को संशोधित करने की आवश्यकता होगी [(1, z), (2, क), (3, ख), (4, ग)]। यदि कोई कामकाज है - इसे विस्तृत किया जाना चाहिए .. – amit

-1

C++ तुम सिर्फ वैक्टर के नक्शे का उपयोग कर सकते हैं, तो जैसे में है जब तक:

int main() { 
    map<int, vector<int> > data; 
    data[0].push_back(1); 
    data[1].push_back(3); 
    data[1].push_back(2); 
    data[0].push_back(5); 
    map<int, vector<int> >::iterator it; 
    for (it = data.begin(); it != data.end(); it++) { 
    vector<int> v = it->second; 
    for (int i = v.size() - 1; i >= 0; i--) { 
     cout << v[i] << ' '; 
    } 
    } 
    cout << '\n'; 
} 

यह प्रिंट:

5 1 2 3 
वैसे ही जैसे आप चाहते हैं

, और आवेषण ओ (लॉग एन) हैं।

+2

यदि आप अगले सूचकांक में 10 को धक्का देने का प्रयास करते हैं तो यह असफल हो जाएगा। – amit

1

आप std::map मैपिंग (इंडेक्स, सम्मिलन-समय) जोड़ों को मानों पर जोड़ सकते हैं, जहां सम्मिलन-समय एक "ऑटोइनक्रिकमेंट" पूर्णांक (SQL शर्तों में) है।जोड़े पर आदेश होना चाहिए

(i, t) < (i*, t*) 

i < i* or t > t* 

कोड में iff:

struct lt { 
    bool operator()(std::pair<size_t, size_t> const &x, 
        std::pair<size_t, size_t> const &y) 
    { 
     return x.first < y.first || x.second > y.second; 
    } 
}; 

typedef std::map<std::pair<size_t, size_t>, int, lt> array_like; 

void insert(array_like &a, int value, size_t i) 
{ 
    a[std::make_pair(i, a.size())] = value; 
} 
+0

मान लें कि हम 0 पर 300 डालते हैं, फिर 100 पर 0, फिर 200 पर 1। क्या होना चाहिए: '[]' फिर '[300]', फिर '10000]', फिर '10000 300]'। लेकिन वास्तव में क्या होता है: '[]', फिर '[((0, 1), 300)] ', फिर' [((0, 2), 100), ((0, 1), 300)] ', अब तक इतना अच्छा है, लेकिन फिर '[((0, 2), 100), ((0, 1), 300), ((1, 3), 200)]'। निष्कर्ष: ऑर्डर आंकड़ों के बिना, इस प्रकार की चीज आमतौर पर करना मुश्किल होती है। –

1

अपनी टिप्पणी के बारे में:

List.Insert() (जो बहुत धीमी है क्योंकि इसे हर तत्व को स्थानांतरित करना है),

सूचियां उनके मूल्यों को स्थानांतरित नहीं करती हैं, वे उस स्थान को ढूंढने के लिए पुन: प्रयास करते हैं, जिसे आप सम्मिलित करना चाहते हैं, सावधान रहें जो आप कहते हैं। यह मेरे जैसे नए लोगों को भ्रमित कर सकता है।

0

डिफ़ॉल्ट रूप से जीसीसी के साथ शामिल एक समाधान रस्सी डेटा संरचना है। यहां documentation है। आम तौर पर, पात्रों के लंबे तारों के साथ काम करते समय रस्सियों को ध्यान में आता है। यहां हमारे पास वर्णों की बजाय int एस है, लेकिन यह वही काम करता है। टेम्पलेट पैरामीटर के रूप में बस int का उपयोग करें। (pair एस, आदि भी हो सकता है)

यहां description of rope on Wikipedia है।

असल में, यह एक द्विआधारी पेड़ का कहना है कि कितने तत्वों बाएँ और दाएँ subtrees में हैं (या समतुल्य जानकारी है, जो क्या रूप आदेश आँकड़े कहा जाता है) है, और ये मायने रखता अपडेट किया जाता है उचित रूप से के रूप में subtrees घुमाया जाता है जब तत्वों को सम्मिलित और हटा दिया जाता है। यह ओ (एलजी एन) संचालन की अनुमति देता है।

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