क्या अजगर के पास एक हल की गई सूची है?


128

जिससे मेरा मतलब एक संरचना से है:

  • x.push()संचालन के लिए ओ (लॉग एन) जटिलता
  • ओ (लॉग एन) एक तत्व को खोजने के लिए जटिलता
  • O (n) गणना करने के लिए जटिलता list(x)जो छँटाई जाएगी

मेरे पास संबंधित प्रदर्शन के बारे में भी प्रश्न था list(...).insert(...)जो अब यहाँ है


memcpyअभी भी एक O (n) ऑपरेशन है। मुझे यकीन नहीं है कि पायथन उपकरणों को कैसे सूचीबद्ध करता है , लेकिन मेरी शर्त यह है कि वे सन्निहित स्मृति में संग्रहीत हैं (निश्चित रूप से लिंक की गई सूची के रूप में नहीं)। यदि वह वास्तव में ऐसा है, तो bisectआपके द्वारा प्रदर्शित प्रविष्टि का जटिलता O (n) होगा
Stephan202

2
अफसोस की बात है कि बॉक्स बाहर नहीं है। लेकिन ग्रांट जेनक की छंटनी करने वालों की लाइब्रेरी बेहतरीन है। stackoverflow.com/a/22616929/284795
कर्नल पैनिक

जवाबों:


52

मानक पायथन सूची किसी भी रूप में क्रमबद्ध नहीं है। मानक हीपेक मॉड्यूल का उपयोग किसी मौजूदा सूची में O (log n) में संलग्न करने और O (लॉग एन) में सबसे छोटे को हटाने के लिए किया जा सकता है, लेकिन यह आपकी परिभाषा में क्रमबद्ध सूची नहीं है।

अजगर के लिए संतुलित पेड़ों के विभिन्न कार्यान्वयन हैं जो आपकी आवश्यकताओं को पूरा करते हैं, जैसे rbtree , RBTree , या pyll


1
; Rbtree के लिए +1, यह बहुत अच्छी तरह से काम करता है (नहीं शुद्ध अजगर, इतना आसान नहीं शायद तैनात करने के लिए, लेकिन मूल कोड शामिल हैं)
विल

12
Sortedcontainers शुद्ध-पायथन है और एक प्रदर्शन तुलना के साथ तेज़-जैसे-सी (rbtree)।
ग्रांटज

"आपकी परिभाषा में कोई क्रमबद्ध सूची नहीं है।" ऐसा कैसे?
कर्नल पैनिक

4
हीपैक केवल सबसे छोटे तत्व को खोजने की अनुमति देता है; ओपी एक ऐसी संरचना की मांग कर रहा था जो ओ (लॉग एन) में किसी भी तत्व को पा सके, जो ढेर नहीं हैं।
मार्टिन वी। लोविस

70

क्या आपके बिग-ओ की आवश्यकताओं का कोई विशेष कारण है? या क्या आप चाहते हैं कि यह जल्दी हो? Sortedcontainers मॉड्यूल शुद्ध पायथन और तेजी से (blist और rbtree की तरह तेजी से के रूप में सी कार्यान्वयन के रूप में) है।

प्रदर्शन की तुलना से पता चलता है यह तेजी से या पर blist की क्रमबद्ध सूची प्रकार के साथ बराबर मानक। यह भी ध्यान दें कि rbtree, RBTree, और PyAVL सॉर्ट किए गए तानाशाही और सेट प्रकार प्रदान करते हैं लेकिन एक सॉर्ट की गई सूची प्रकार नहीं है।

यदि प्रदर्शन एक आवश्यकता है, तो हमेशा बेंचमार्क को याद रखें। एक मॉड्यूल जो बिग-ओ नोटेशन के साथ तेज़ होने के दावे की पुष्टि करता है, जब तक कि यह बेंचमार्क तुलनाओं को नहीं दिखाता है, तब तक संदेह होना चाहिए।

डिस्क्लेमर: मैं पाइथन सॉर्टेडकॉनटेनर्स मॉड्यूल का लेखक हूं।


स्थापना:

pip install sortedcontainers

उपयोग:

>>> from sortedcontainers import SortedList
>>> l = SortedList()
>>> l.update([0, 4, 1, 3, 2])
>>> l.index(3)
3
>>> l.add(5)
>>> l[-1]
5

4
वास्तव में मैंने बाइसेक्ट के खिलाफ सॉर्टेक्नोक्टर्स की तुलना की: सॉर्टेड लिस्ट के 0.0845024989976लिए। () बनाम 0.596589182518बिसेक्ट के लिए। पिन (), इस प्रकार गति में 7x का अंतर! और मैं सूची की लंबाई के साथ गति अंतराल के बढ़ने की उम्मीद करता हूं क्योंकि ओ (एन) में bisect.insort () करते समय ओ (लॉग एन) में सॉर्टकंटेनर्स सम्मिलन प्रकार काम करता है।
जबोर

1
@ विस्तृत क्योंकि बिसेक अभी भी एक सूची का उपयोग करता है, इसलिए प्रविष्टि बनी हुई हैO(n)
njzk2

34

हालांकि मैंने अभी भी बुनियादी पायथन सूची संचालन की "बड़ी ओ" गति की जांच नहीं की है, bisectमानक मॉड्यूल शायद इस मामले में भी ध्यान देने योग्य है:

import bisect
L = [0, 100]

bisect.insort(L, 50)
bisect.insort(L, 20)
bisect.insort(L, 21)

print L
## [0, 20, 21, 50, 100]

i = bisect.bisect(L, 20)
print L[i-1], L[i]
## 20, 21

पुनश्च। bisectसंदर्भित प्रश्न में आह, क्षमा, का उल्लेख है। फिर भी, मुझे लगता है कि अगर यह जानकारी यहाँ होगी तो बहुत नुकसान नहीं होगा)

पी पी एस। और सीपीथॉन सूची वास्तव में सरणियां हैं (नहीं, कहते हैं, स्किपलिस्ट या आदि)। ठीक है, मुझे लगता है कि उन्हें कुछ सरल होना चाहिए, लेकिन मेरे लिए, नाम थोड़ा भ्रामक है।


इसलिए, अगर मैं गलत नहीं हूँ, तो बिज़ेक्ट / लिस्ट स्पीड शायद होगी:

  • एक धक्का के लिए (): ओ (एन) सबसे खराब स्थिति के लिए;
  • खोज के लिए: यदि हम सरणी अनुक्रमण की गति को O (1) मानते हैं, तो खोज O (लॉग (n)) ऑपरेशन होनी चाहिए;
  • सूची निर्माण के लिए: O (n) सूची की प्रतिलिपि बनाने की गति होनी चाहिए, अन्यथा यह उसी सूची के लिए O (1) है

Upd। टिप्पणियों में एक चर्चा के बाद, मुझे इन एसओ प्रश्नों के बारे में बताएं: पायथन की सूची को कैसे लागू किया गया है और अजगर सूची के कार्यों की रनटाइम जटिलता क्या है


धक्का () ओ में होना चाहिए (लॉग एन) क्योंकि सूची पहले से ही क्रमबद्ध है।
इस्टानी

1
हो सकता है कि मुझे "एक सम्मिलित सेशन के लिए" कहना चाहिए था । वैसे भी, कि एक साल पहले के बारे में था तो अब मैं आसानी से चीजों को मिला या कुछ याद कर सकते हैं
was ョ

आप हमेशा O (लॉग एन) में एक सॉर्ट की गई सूची में मान डाल सकते हैं, बाइनरी खोज देख सकते हैं। पुश () को एक सम्मिलित ऑपरेशन के रूप में परिभाषित किया गया है।
एस्टनी

2
सच। लेकिन डालने का स्थान खोजने के दौरान वास्तव में ओ (लॉग एन) ऑप्स ले जाएगा, वास्तविक इंसर्ट (यानी डेटा संरचना में तत्व को जोड़ना) शायद उस संरचना पर निर्भर करता है (एक क्रमबद्ध सरणी में एक तत्व डालने पर विचार करें)। और जैसा कि पायथन सूचियां वास्तव में सरणियां हैं , इसमें O (n) लग सकता है। टिप्पणियों के लिए आकार की सीमा के कारण, मैं उत्तर के पाठ से दो संबंधित SO प्रश्नों को जोड़ूंगा (ऊपर देखें)।
ジ ー ジ

अच्छा तर्क। मुझे पता नहीं था कि पायथन में सरणियों के रूप में संभाला गया था।
इस्टानी

7
import bisect

class sortedlist(list):
    '''just a list but with an insort (insert into sorted position)'''
    def insort(self, x):
        bisect.insort(self, x)

निहित प्रविष्टि () को bisect.insort () में O (n)
j314erre

6

हालांकि यह (अभी तक) एक कस्टम खोज फ़ंक्शन प्रदान नहीं करता है, heapqमॉड्यूल आपकी आवश्यकताओं के अनुरूप हो सकता है। यह एक नियमित सूची का उपयोग कर एक ढेर कतार लागू करता है। आपको अपने स्वयं के कुशल सदस्यता परीक्षण को लिखना होगा जो कतार की आंतरिक संरचना का उपयोग करता है (जो कि ओ (लॉग एन) में किया जा सकता है , मैं कहूंगा ...)। एक नकारात्मक पहलू है: एक सॉर्ट की गई सूची निकालने में जटिलता ओ (एन लॉग एन) है


यह अच्छा है, लेकिन मुश्किल है।
एलिया एन।

3
ढेर में ओ (लॉग एन) सदस्यता परीक्षण कैसे हो सकता है? यदि आप मान x की तलाश कर रहे हैं, तो यदि आप x से कुछ बड़ा पाते हैं, तो आप एक शाखा को देखना बंद कर सकते हैं, लेकिन x के यादृच्छिक मान के लिए यह एक पत्ते पर 50% होने की संभावना है, और आप संभवतः बहुत अधिक नहीं कर सकते।
बाजार

1

मैं biscectया sortedcontainersमॉड्यूल का उपयोग करेगा । मैं वास्तव में अनुभवी नहीं हूं, लेकिन मुझे लगता है कि heapqमॉड्यूल काम करता है। इसमें एHeap Queue


0

अजगर पर अपनी खुद की छँटाई को लागू करना कठिन नहीं हो सकता है। नीचे अवधारणा का प्रमाण दिया गया है:

import bisect

class sortlist:
    def __init__(self, list):
        self.list = list
        self.sort()
    def sort(self):
        l = []
        for i in range(len(self.list)):
            bisect.insort(l, self.list[i])
        self.list = l
        self.len = i
    def insert(self, value):
        bisect.insort(self.list, value)
        self.len += 1
    def show(self):
        print self.list
    def search(self,value):
        left = bisect.bisect_left(self.list, value)
        if abs(self.list[min([left,self.len-1])] - value) >= abs(self.list[left-1] - value):
            return self.list[left-1]
        else:
            return self.list[left]

list = [101, 3, 10, 14, 23, 86, 44, 45, 45, 50, 66, 95, 17, 77, 79, 84, 85, 91, 73]
slist = sortlist(list)
slist.show()
slist.insert(99)
slist.show()
print slist.search(100000000)
print slist.search(0)
print slist.search(56.7)

========= परिणाम ============

[3, 10, 14, 17, 23, 44, 45, 45, 50, 66, 73, 77, 79, 84, 85, 86, 91, 95, 101]

[3, 10, 14, 17, 23, 44, 45, 45, 50, 66, 73, 77, 79, 84, 85, 86, 91, 95, 99, 101]

101

3

50

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.