किस तरह का एल्गोरिथ्म ज्यादातर सॉर्ट किए गए डेटा पर सबसे अच्छा काम करता है? [बन्द है]


174

ज्यादातर सॉर्ट किए गए डेटा पर कौन सा छंटाई एल्गोरिथ्म सबसे अच्छा काम करता है?


संदर्भ की कमी से अनुमान लगाते हुए - आप एक इन-मेमोरी सॉर्ट के बारे में पूछ रहे हैं जो डिस्क पर मध्यवर्ती परिणामों को फैलाने की आवश्यकता नहीं है?
जोनाथन लेफ्लर

1
इन एनिमेशन के अनुसार ज्यादातर सॉर्ट किए गए डेटा पर प्रविष्टि सॉर्टिंग सबसे अच्छा काम करती है।
dopple

जवाबों:


259

एनिमेटेड जिफ देखने के उच्च वैज्ञानिक तरीके के आधार पर मैं कहूंगा कि प्रविष्टि और बबल प्रकार अच्छे उम्मीदवार हैं।


19
इस तरह से एक उत्कृष्ट लिंक है, यश और
21-11 को

5
बबल सॉर्ट भयानक है। यह हमेशा O (n ^ 2) होता है। कम से कम कृपया अपने उत्तर के लिए इसे सही से लें।
22

79
jjnguy, यह सिर्फ सादा गलत है। मुझे लगता है कि आपको अपने एल्गोरिदम वर्ग को फिर से लेने की आवश्यकता है। लगभग सॉर्ट किए गए डेटा पर (यह अनुकूली मामला है) यह ओ (एन) है। हालाँकि, यह डेटा के माध्यम से 2 पास लेता है और सम्मिलन केवल लगभग सॉर्ट किए गए डेटा के लिए 1 लेता है, जो प्रविष्टि को विजेता बनाता है। बबल अभी भी अच्छा है
mmcdole

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

5
जब मैंने कोशिश की तो वह लिंक टूट गया था। इसके बजाय इसे आज़माएं: सॉर्टिंग-algorithms.com
माइकल ला

107

केवल कुछ आइटम => बीमा क्षेत्र

आइटम ज्यादातर पहले से ही सॉर्ट किए जाते हैं => इंसर्ट सोर

सबसे खराब स्थिति के बारे में चिंतित => HEAP SORT

एक अच्छे औसत-मामले के परिणाम में रुचि => QUICKSORT

आइटम घने ब्रह्माण्ड से खींचे जाते हैं => BUCKET SORT

जितना संभव हो उतना कम कोड लिखने की इच्छा => बीमा क्षेत्र


1
यह ठीक उसी तरह का उत्तर है जिसकी मैं तलाश कर रहा हूं, मैं किताबें पढ़ता हूं, लेकिन मुझे विशेष मामलों में एलोगोरिथम्स के चयन के लिए कोई स्पष्ट स्पष्टीकरण नहीं मिलता है, क्या आप इसे विस्तृत कर सकते हैं या एक लिंक पारित कर सकते हैं ताकि मैं कुत्ते में प्रवेश कर सकूं यह थोड़ा अधिक है? धन्यवाद
सिमरन कौर

9
आपको "डेटा पहले से ही एक और मानदंड => MERGE SORT" से जोड़ा जाना चाहिए
जिम हंज़िकर

30

timsort

Timsort " कई प्रकार के आंशिक रूप से ऑर्डर किए गए सरणियों (lg (N! तुलनात्मक तुलना में कम) और N-1 के रूप में कम) पर " अलौकिक , स्थिर, प्राकृतिक विलय "है। अजगर का बनाया हुआsort()कुछ समय के लिए इस एल्गोरिथ्म का उपयोग किया है, जाहिर है अच्छे परिणामों के साथ। यह विशेष रूप से इनपुट में आंशिक रूप से क्रमबद्ध क्रमों का पता लगाने और लाभ उठाने के लिए डिज़ाइन किया गया है, जो अक्सर वास्तविक डेटासेट में होते हैं। यह वास्तविक दुनिया में अक्सर ऐसा होता है कि किसी सूची में वस्तुओं की अदला-बदली की तुलना में बहुत अधिक महंगा होता है, क्योंकि आमतौर पर बस पॉइंटर्स को स्वैप किया जाता है, जो बहुत बार टाइमसॉर्ट को एक उत्कृष्ट विकल्प बनाता है। हालांकि, यदि आप जानते हैं कि आपकी तुलना हमेशा बहुत सस्ती है (उदाहरण के लिए, 32-बिट पूर्णांक को सॉर्ट करने के लिए एक खिलौना प्रोग्राम लिखना), अन्य एल्गोरिदम मौजूद हैं जो बेहतर प्रदर्शन करने की संभावना रखते हैं। टाइमसॉर्ट का लाभ उठाने का सबसे आसान तरीका निश्चित रूप से पायथन का उपयोग करना है, लेकिन चूंकि पायथन खुला स्रोत है इसलिए आप कोड उधार लेने में भी सक्षम हो सकते हैं। वैकल्पिक रूप से, ऊपर दिए गए विवरण में अपने स्वयं के कार्यान्वयन को लिखने के लिए पर्याप्त विवरण शामिल हैं।


16
log (n!) Ο (n * log (n)) है इसलिए यह "अलौकिक" नहीं है।
JFS

: यहाँ जावा कार्यान्वयन JDK7 में आ रहा है cr.openjdk.java.net/~martin/webrevs/openjdk7/timsort/raw_files/...
टिम

log (n) तेज नहीं है। wolframalpha.com/input/?i=plot Islog(N !) , {N, 0,1000}]
बेहरोज

9
@ जेएफ सेबेस्टियन: टाइम lg(n!)-सॉर्ट, लगभग सभी तरह की सरणी पर तुलना की तुलना में बहुत तेज है , नीचे सभी तरह से O(n)! | @behrooz: नहीं तुलना प्रकार की तुलना में बेहतर औसत मामला हो सकता है O(n log n), और lg(n!)है O(n log n)। इसलिए टाइमसॉर्ट का सबसे खराब मामला किसी भी अन्य तुलनात्मक प्रकार की तुलना में असमान रूप से बुरा नहीं है। इसके अलावा इसका सबसे अच्छा मामला किसी भी अन्य तुलनात्मक प्रकार से बेहतर या बराबर है।
आर्टेलियस

3
Timsort अभी भी सबसे खराब स्थिति में O (nlogn) है, लेकिन इसके अच्छे मामले काफी सुखदायक हैं। यहाँ कुछ रेखांकन के साथ तुलना की जा रही है: stromberg.dnsalias.org/~strombrg/sort-comparison ध्यान दें कि साइथॉन में टाइमशॉर्ट लगभग उतना ही तेज़ नहीं था, जितना कि पायथन द्वारा निर्मित सी। टाइमशॉर्ट में सी।
यूज़र 1277476

19

निम्नलिखित व्यवहार के साथ सम्मिलन क्रमबद्ध करें:

  1. kस्लॉट्स में प्रत्येक तत्व के लिए 1..n, पहले जांचें कि क्या el[k] >= el[k-1]। यदि ऐसा है, तो अगले तत्व पर जाएं। (स्पष्ट रूप से पहला तत्व छोड़ें।)
  2. यदि नहीं, 1..k-1सम्मिलन स्थान निर्धारित करने के लिए तत्वों में बाइनरी-खोज का उपयोग करें , तो तत्वों को खत्म कर दें। (आप इसे केवल तभी कर सकते हैं यदि कुछ थ्रेशोल्ड मान k>Tकहाँ Tहै; छोटे के साथ kयह ओवरकिल है।)

यह विधि कम से कम तुलना की संख्या बनाती है।


मुझे लगता है कि बबल सॉर्ट इसे हरा सकता है यदि अनसर्टेड एलिमेंट्स की संख्या बहुत कम है (जैसे, एक या दो), लेकिन सामान्य तौर पर यह मुझे सबसे अच्छा समाधान लगता है।
सोल

चरण 1 के कारण, पहले से ही हल किए गए किसी भी तत्व के लिए डेटा की तुलना और शून्य-चाल बिल्कुल एक है, जो स्पष्ट रूप से सबसे अच्छा है जो आप कर सकते हैं। चरण 2 वह है जिस पर आप सुधार कर सकते हैं, लेकिन बुलबुला एक ही संख्या में तत्वों को स्थानांतरित करेगा और आपके निहितार्थ के आधार पर अधिक तुलनाएं हो सकती हैं।
जेसन कोहेन

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

मैंने इसे लागू करने की कोशिश की, लेकिन द्विआधारी खोज में बहुत सुधार नहीं हुआ है क्योंकि आपको अभी भी तत्व को सम्मिलित करने के लिए पूरे ब्लॉक को स्थानांतरित करना है। तो 2xrange के बजाय आपको रेंज + लॉगब (रेंज) मिलती है।
यह

11

आत्मनिरीक्षण का प्रयास करें। http://en.wikipedia.org/wiki/Introsort

यह क्विकसॉर्ट आधारित है, लेकिन यह सबसे खराब स्थिति वाले व्यवहार से बचता है जो क्विकॉर्ट के पास लगभग छांटे गए सूचियों के लिए है।

चाल यह है कि यह सॉर्ट-एल्गोरिथ्म उन मामलों का पता लगाता है जहां क्विकॉर्ट सबसे खराब स्थिति में जाता है और सॉर्ट करने या विलय करने के लिए स्विच करता है। लगभग गैर-विभाजन विभाजन विधि द्वारा लगभग छांटे गए विभाजन का पता लगाया जाता है और सम्मिलन प्रकार का उपयोग करके छोटे विभाजन को संभाला जाता है।

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

यदि आप C ++ प्रोग्रामर हैं तो अपने std :: सॉर्ट एल्गोरिथ्म की जांच करें। यह पहले से ही आंतरिक रूप से आत्मनिरीक्षण का उपयोग कर सकता है।


7

Splaysort एक अस्पष्ट छँटाई विधि है जो कि आवारा पेड़ों , एक प्रकार के अनुकूली बाइनरी ट्री पर आधारित है । Splaysort न केवल आंशिक रूप से सॉर्ट किए गए डेटा के लिए, बल्कि आंशिक रूप से रिवर्स-सॉर्ट किए गए डेटा, या वास्तव में किसी भी डेटा के लिए अच्छा है, जिसमें किसी भी प्रकार का पूर्व-मौजूदा क्रम है। यह सामान्य मामले में O (nlogn) है, और O (n) उस मामले में जहां डेटा को किसी तरह से सॉर्ट किया जाता है (आगे, रिवर्स, ऑर्गन-पाइप, आदि)।

प्रविष्टि सॉर्ट पर इसका बड़ा लाभ यह है कि यह डेटा में बिल्कुल भी सॉर्ट नहीं किए जाने पर O (n ^ 2) व्यवहार पर वापस नहीं आता है, इसलिए आपको यह सुनिश्चित करने की आवश्यकता नहीं है कि डेटा का उपयोग करने से पहले आंशिक रूप से सॉर्ट किया गया है ।

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

Splaysort पर एक पेपर सॉफ्टवेयर - प्रैक्टिस एंड एक्सपीरियंस में प्रकाशित किया गया था।



5

पहले से ही सॉर्ट किए गए डेटा पर डायजेक्स्ट्रा का स्मूदसॉर्ट एक शानदार सॉर्ट है। यह एक हेस्पोर्ट वेरिएंट है जो O (n lg n) सबसे खराब स्थिति और O (n) बेस्ट-केस में चलता है। मैंने एल्गोरिथ्म का विश्लेषण लिखा है, यदि आप उत्सुक हैं कि यह कैसे काम करता है।

प्राकृतिक मर्जर्ट इसके लिए एक और बहुत अच्छा है - यह एक बॉटम-अप मर्जर्ट वैरिएंट है जो इनपुट को कई अलग-अलग सॉर्ट किए गए श्रेणियों के संयोजन के रूप में मानकर काम करता है, फिर मर्ज एल्गोरिथ्म का उपयोग करके उन्हें एक साथ जोड़ देता है। आप इस प्रक्रिया को तब तक दोहराते हैं जब तक कि सभी इनपुट रेंज सॉर्ट न हो जाएं। यह O (n) समय में चलता है यदि डेटा पहले से ही सॉर्ट किया गया है और O (n lg n) सबसे खराब स्थिति में है। यह बहुत ही सुंदर है, हालांकि व्यवहार में यह कुछ अन्य अनुकूली प्रकारों जैसे कि टिम्सॉर्ट या स्मूथोर्ट के रूप में अच्छा नहीं है।


अन्य सॉर्टिंग एल्गोरिदम की तुलना में स्मूथर्स के रनटाइम स्थिरांक क्या हैं? (यानी एक ही डेटा के लिए रनटाइम (सुचारू) / रनटाइम (सम्मिलन)
Arne Babenhauserheide

4

यदि तत्व पहले से ही सॉर्ट किए गए हैं या केवल कुछ ही तत्व हैं, तो यह प्रविष्टि सॉर्ट के लिए एक सही उपयोग मामला होगा!


3

प्रविष्टि प्रकार O (n + व्युत्क्रम की संख्या) समय लेता है।

उलटा एक जोड़ा है (i, j)ऐसा i < j && a[i] > a[j]। यानी एक आउट-ऑफ-ऑर्डर जोड़ी।

"लगभग छांटे जाने" का एक उपाय है, व्युत्क्रमों की संख्या --- कोई कुछ व्युत्क्रमों के साथ डेटा का अर्थ "लगभग क्रमबद्ध डेटा" ले सकता है। यदि किसी को व्युत्क्रमानुपाती होने की संख्या ज्ञात है (उदाहरण के लिए, आपने ओ (1) तत्वों को क्रमबद्ध सूची में जोड़ दिया है), प्रविष्टि सॉर्ट में O (n) समय लगता है।


2

जैसा कि बाकी सभी ने कहा, भोले क्विकसॉर्ट से सावधान रहें - जिसमें सॉर्ट किए गए या लगभग सॉर्ट किए गए डेटा पर O (N ^ 2) का प्रदर्शन हो सकता है। फिर भी, पिवट की पसंद के लिए एक उपयुक्त एल्गोरिथ्म के साथ (या तो यादृच्छिक या मध्य-तीन - क्विकॉर्ट के लिए एक पिवेट चुनना देखें ), क्विकॉर्ट अभी भी पूरी तरह से काम करेगा।

सामान्य तौर पर, एल्गोरिदम जैसे डालने के प्रकार को चुनने में कठिनाई यह तय करने में होती है कि डेटा पर्याप्त रूप से ऑर्डर से बाहर है कि क्विकॉर्ट वास्तव में जल्दी होगा।


2

मैं यहाँ सभी उत्तरों के बहाने नहीं जा रहा हूँ, क्योंकि मुझे लगता है कि वास्तविक उत्तरों को प्राप्त करने के लिए एल्गोरिदम को कोड करना और उन्हें प्रतिनिधि डेटा नमूनों के विरुद्ध प्रोफाइलिंग की आवश्यकता हो सकती है। लेकिन मैं इस सवाल के बारे में पूरी शाम सोच रहा हूं, और यहां मेरे साथ अब तक क्या हुआ है, और कुछ इस बात का अनुमान लगाते हैं कि सबसे अच्छा काम कहां होता है।

बता दें कि N कुल आइटमों की संख्या है, M क्रम-आउट संख्या है।

बबल सॉर्ट को 2 * M + 1 जैसा कुछ बनाना होगा जो सभी N आइटम से होकर गुजरेगा। यदि M बहुत छोटा है (0, 1, 2?), मुझे लगता है कि यह हराना बहुत कठिन होगा।

यदि M छोटा है (लॉग एन से कम कहें), तो प्रविष्टि सॉर्ट में औसत औसत प्रदर्शन होगा। हालाँकि, जब तक कोई चाल नहीं चल रही है, तब तक यह बहुत खराब स्थिति वाला प्रदर्शन होगा। (सही! यदि ऑर्डर में अंतिम आइटम पहले आता है, तो आपको हर एक आइटम को सम्मिलित करना होगा, जहां तक ​​मैं देख सकता हूं, जो प्रदर्शन को मार देगा।) मैं अनुमान लगा रहा हूं कि इसके लिए एक अधिक विश्वसनीय छंटनी एल्गोरिदम है। मामला, लेकिन मुझे नहीं पता कि यह क्या है।

यदि M बड़ा है (लॉग एन की तुलना में बराबर या महान है), आत्मनिरीक्षण सॉर्ट लगभग निश्चित रूप से सबसे अच्छा है।

उस सभी के लिए अपवाद: यदि आप वास्तव में समय से पहले जानते हैं कि कौन से तत्व अनसोल्ड हैं, तो आपकी सबसे अच्छी शर्त उन वस्तुओं को बाहर निकालना होगा, उन्हें आत्मनिरीक्षण प्रकार का उपयोग करके सॉर्ट करना होगा, और दो सॉर्ट की गई सूचियों को एक साथ एक क्रमबद्ध सूची में मर्ज करना होगा। यदि आप जल्दी से पता लगा सकते हैं कि कौन सी वस्तुएं ऑर्डर से बाहर हैं, तो यह एक अच्छा सामान्य समाधान होगा - लेकिन मैं ऐसा करने के लिए एक सरल तरीका नहीं समझ पाया।

आगे के विचार (रात भर): यदि M + 1 <N / M, तो आप एक पंक्ति में N / M के रन की तलाश करने वाली सूची को स्कैन कर सकते हैं, जिसे क्रमबद्ध किया गया है, और फिर उस आउट का पता लगाने के लिए दोनों दिशाओं में विस्तार करें -चिजें मँगाओ। यह सबसे अधिक 2N तुलना में ले जाएगा। फिर आप अनसोल्ड आइटम को सॉर्ट कर सकते हैं, और दो सूचियों पर एक सॉर्ट मर्ज कर सकते हैं। कुल तुलना 4N + M log2 (M) जैसी किसी चीज से कम होनी चाहिए, जो कि किसी गैर-विशिष्ट सॉर्टिंग रूटीन को मात देने वाली है, मुझे लगता है। (इससे भी आगे सोचा: यह मेरे विचार से बहुत मुश्किल है, लेकिन मुझे अभी भी लगता है कि यह यथोचित संभव है।)

प्रश्न की एक और व्याख्या यह है कि कई आउट-ऑफ-ऑर्डर आइटम हो सकते हैं, लेकिन वे सूची में कहाँ होना चाहिए, इसके बहुत करीब हैं। (कल्पना करें कि एक क्रमबद्ध सूची के साथ शुरू करें और उसके बाद आने वाले हर दूसरे आइटम को स्वैप करें।) उस स्थिति में मुझे लगता है कि बुलबुला सॉर्ट बहुत अच्छा करता है - मुझे लगता है कि पास की संख्या एक आइटम के बाहर सबसे दूर के लिए आनुपातिक होगी। है। प्रविष्टि सॉर्ट खराब रूप से काम करेगा, क्योंकि ऑर्डर आइटम में से प्रत्येक एक प्रविष्टि को ट्रिगर करेगा। मुझे लगता है कि आत्मनिरीक्षण का संदेह है या ऐसा कुछ भी अच्छा काम करेगा।


1

यदि आपको एल्गोरिदम, डेटा संरचनाओं या ऊपर दी गई किसी भी लिंक को छांटने के लिए विशिष्ट कार्यान्वयन की आवश्यकता है, तो क्या मैं आपको कोडप्लेक्स पर उत्कृष्ट "डेटा संरचना और एल्गोरिदम" परियोजना की सिफारिश कर सकता हूं ?

इसमें वह सब कुछ होगा जो आपको पहिया को फिर से लगाए बिना चाहिए।

बस नमक का मेरा छोटा सा दाना।


1

जवाबों में इस उद्देश्य के लिए छँटाई एल्गोरिदम का यह अच्छा संग्रह, गनोम सॉर्ट की कमी लगता है , जो उपयुक्त भी होगा, और शायद कम से कम कार्यान्वयन के प्रयास की आवश्यकता होती है।


0

प्रविष्टि सॉर्ट सबसे अच्छा मामला हे (n) सॉर्ट किए गए इनपुट पर। और यह ज्यादातर सॉर्ट किए गए इनपुट (त्वरित सॉर्ट से बेहतर) पर बहुत करीब है।


0

पोंप ट्राई हीप। मेरा मानना ​​है कि यह O (n lg n) तरह का सबसे अधिक सुसंगत है।


संगति यहाँ चिंता का विषय नहीं है। हीप्सर्ट सॉर्ट किए गए डेटा पर भी O (n lg n) देगा, और वास्तव में अनुकूल नहीं है। व्यवहार्य विकल्प हो सकते हैं: सम्मिलन प्रकार, Timsort और Bubblesort।
अधिकतम

0

बबल-सॉर्ट (या, अभी तक, द्वि-दिशात्मक बबल सॉर्ट) ज्यादातर सॉर्ट किए गए सूचियों के लिए आदर्श है, हालांकि मैंने शर्त लगाई कि एक कंघी कंघी-सॉर्ट (बहुत कम प्रारंभिक अंतराल के आकार के साथ) सूची के एनएन होने पर थोड़ा तेज होगा। टी काफी पूरी तरह से हल के रूप में। बबल-सॉर्ट करने के लिए तरह तरह के गिरावट।


0

अच्छी तरह से यह उपयोग के मामले पर निर्भर करता है। यदि आप जानते हैं कि कौन से तत्व बदले गए हैं, तो निकालें और सम्मिलित करना सबसे अच्छा मामला होगा जहां तक ​​मेरा संबंध है।


1
एल्गोरिथ्म दक्षता का यह "जहां तक ​​मेरा सवाल है" मेरा दिन उज्ज्वल हो गया :) गंभीर होने के नाते, हालांकि, "हटाने और डालने" को लिखने का क्या मतलब था कि इंसर्शन सॉर्ट करें (जो पहले से ही पिछले उत्तरों में उल्लिखित था), या क्या आप प्रस्ताव देते हैं एल्गोरिथ्म का एक नया प्रकार? यदि हां, तो कृपया अपने उत्तर का विस्तार करें।
yoniLavi

0

बबल सॉर्ट निश्चित रूप से विजेता है राडार पर अगला प्रविष्टि सॉर्ट होगा।


4
स्पष्टीकरण के साथ अपना उत्तर पोस्ट करें;

1
मैं आपको सुझाव दूंगा कि डुप्लिकेट से बचने के लिए पोस्ट करने से पहले उपलब्ध उत्तरों पर एक नज़र डालें।
angainor

-1

QuickSort से दूर रखें - पूर्व-सॉर्ट किए गए डेटा के लिए यह बहुत अक्षम है। प्रविष्टि सॉर्ट संभव के रूप में कुछ मानों को स्थानांतरित करके लगभग सॉर्ट किए गए डेटा को संभालता है।


-1 क्विकॉर्ट के हर औद्योगिक कार्यान्वयन में एक उचित धुरी चयन है
स्टीफन

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