क्यों संग्रह। एसॉर्ट क्विकॉर्ट के बजाय मर्ज सॉर्ट का उपयोग करता है?


101

हम जानते हैं कि त्वरित सॉर्ट सबसे तेज़ सॉर्टिंग एल्गोरिथम है।

JDK6 collections.sortत्वरित सॉर्ट के बजाय मर्ज सॉर्ट एल्गोरिथ्म का उपयोग करता है। लेकिन Arrays.sort त्वरित सॉर्ट एल्गोरिथ्म का उपयोग करता है।

क्या कारण है। त्वरित सॉर्ट के बजाय कलेक्शन.सॉर्ट मर्ज सॉर्ट का उपयोग करता है?


3
जब तक आपको जवाब देने के लिए एक जेडीके लेखक नहीं मिल सकता है, तब तक आप अनुमान लगाने वाले हैं। असली सवाल नहीं।
लोर्ने

4
@ ईजेपी अच्छा बिंदु, लेकिन निश्चित रूप से "नहीं रचनात्मक" सही बंद करने का कारण है। यह मेरे लिए स्पष्ट है कि यहाँ क्या प्रश्न है।
डंकन जोन्स

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

4
एक अनुमान: Quicksort स्थिर नहीं है, Mergesort है। आदिम के लिए, एक स्थिर / गैर-स्थिर सॉर्ट अप्रासंगिक है, वस्तुओं के लिए (या कम से कम, आपको एक अस्थिर प्रकार के खिलाफ दायर किए गए कीड़े मिल सकते हैं)।
पारसीफाल

2
@ ईजेपी, जेडीके लेखकों के इरादों को सार्वजनिक होने से रोक नहीं रहा है। एक बार सार्वजनिक होने के बाद, हमें जवाब देने के लिए लेखक की आवश्यकता नहीं है। यह वास्तव में एक जवाब पाने के लिए संभव है जो कि जेडीके लेखक के जवाब के बिना भी अधिक-से-अनुमान है।
पचेरियर

जवाबों:


188

अत्यधिक संभावना जोश बलोच से § :

मैंने इन विधियों को लिखा था, इसलिए मुझे लगता है कि मैं जवाब देने के लिए योग्य हूं। यह सच है कि एक भी सर्वश्रेष्ठ छँटाई एल्गोरिथ्म नहीं है। विलय के मुकाबले क्विकॉर्ट के पास दो बड़ी कमियां हैं:

  1. यह स्थिर नहीं है (जैसा कि पार्सिफल नोट किया गया है)।

  2. यह n लॉग एन प्रदर्शन की गारंटी नहीं देता है ; यह पैथोलॉजिकल इनपुट पर द्विघात प्रदर्शन को नीचा दिखा सकता है।

स्थिरता आदिम प्रकारों के लिए एक गैर-मुद्दा है, क्योंकि समानता (मूल्य) समानता से अलग पहचान की कोई धारणा नहीं है। और द्विघात और मैकाइरोले के कार्यान्वयन (या बाद में दोहरी धुरी क्विकॉर्ट के लिए ) के लिए व्यवहार में एक समस्या के रूप में द्विघात व्यवहार की संभावना को नहीं माना गया था , यही कारण है कि इन क्विकसॉर्ट वेरिएंट का उपयोग आदिम प्रकार के लिए किया गया था।

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

यह एक अच्छा पक्ष लाभ है कि मर्ज सॉर्ट एन लॉग एन (समय) के प्रदर्शन की कोई गारंटी नहीं है कि इनपुट क्या है। बेशक एक डाउन साइड है: क्विक सॉर्ट एक "जगह में" सॉर्ट है: इसे केवल एन एन बाहरी स्थान (कॉल स्टैक को बनाए रखने के लिए) की आवश्यकता होती है। मर्ज, सॉर्ट, दूसरी ओर, ओ (एन) बाहरी स्थान की आवश्यकता होती है। अगर इनपुट ऐरे लगभग छांटा गया है, तो टिमर्ट वेरिएंट (जावा एसई 6 में पेश किया गया) को काफी कम जगह (ओ (के)) की आवश्यकता होती है।

इसके अलावा, निम्नलिखित प्रासंगिक है:

Java.util.Arrays.sort और (परोक्ष रूप से) java.util.Collections.sort द्वारा ऑब्जेक्ट एल्गोरिदम को सॉर्ट करने के लिए उपयोग किया जाने वाला एल्गोरिथ्म एक "संशोधित मर्जोर्ट (जिसमें मर्ज को छोड़ दिया जाता है यदि कम सबलिस्ट में उच्चतम तत्व से कम है) उच्च स्तरीय सूची में सबसे कम तत्व)। " यह एक यथोचित तेजी से स्थिर प्रकार है जो ओ (एन लॉग एन) प्रदर्शन की गारंटी देता है और ओ (एन) अतिरिक्त स्थान की आवश्यकता होती है। अपने दिन में (यह 1997 में यहोशू बलोच द्वारा लिखा गया था), यह एक अच्छा विकल्प था, लेकिन आज लेकिन हम बहुत बेहतर कर सकते हैं।

2003 के बाद से, पायथन की सूची के प्रकार ने टाइमस्टॉर्ट (टिम पीटर्स के बाद, जिसने इसे लिखा था) के रूप में ज्ञात एक एल्गोरिथ्म का उपयोग किया है। यह एक स्थिर, अनुकूली, पुनरावृत्त विलय है, जिसे आंशिक रूप से सॉर्ट किए गए सरणियों पर चलने के दौरान n लॉग (n) तुलना से बहुत कम की आवश्यकता होती है, जबकि यादृच्छिक सरणियों पर चलने पर एक पारंपरिक विलय पर तुलनीय प्रदर्शन की पेशकश करता है। जैसे सभी उचित मर्जर्ट्स टाइमसोर्ट स्थिर हैं और ओ (एन लॉग एन) समय (सबसे खराब स्थिति) में चलता है। सबसे खराब स्थिति में, timsort को n / 2 ऑब्जेक्ट संदर्भ के लिए अस्थायी संग्रहण स्थान की आवश्यकता होती है; सबसे अच्छे मामले में, इसे केवल एक छोटे से स्थिर स्थान की आवश्यकता होती है। वर्तमान कार्यान्वयन के साथ इसका विरोध करें, जिसे हमेशा n ऑब्जेक्ट संदर्भों के लिए अतिरिक्त स्थान की आवश्यकता होती है, और केवल लगभग सॉर्ट की गई सूचियों पर n लॉग एन की धड़कन होती है।

Timsort का विस्तार से वर्णन यहाँ किया गया है: http://svn.python.org/projects/python/trunk/Objects/listsort.txt

टिम पीटर्स का मूल कार्यान्वयन सी। में लिखा गया है। जोशुआ बलोच ने इसे सी से जावा में पोर्ट किया और अंत में परीक्षण किया, बेंचमार्क किया और परिणामी कोड को बड़े पैमाने पर ट्यून किया। परिणामी कोड java.util.Arrays.sort के लिए एक ड्रॉप-इन प्रतिस्थापन है। अत्यधिक ऑर्डर किए गए डेटा पर, यह कोड वर्तमान कार्यान्वयन (हॉटस्पॉट सर्वर वीएम पर) के रूप में 25 गुना तेजी से चल सकता है। यादृच्छिक डेटा पर, पुराने और नए कार्यान्वयन की गति तुलनीय है। बहुत कम सूचियों के लिए, नया कार्यान्वयन काफी तेजी से होता है कि पुराना यादृच्छिक डेटा पर भी (क्योंकि यह अनावश्यक डेटा कॉपी से बचा जाता है)।

इसके अलावा, देखें कि क्या जावा 7 मेथड अरसे के लिए टिम सॉर्ट का उपयोग कर रहा है।

वहाँ एक "सबसे अच्छा" विकल्प नहीं है। कई अन्य चीजों की तरह, यह ट्रेडऑफ के बारे में है।

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