शैक्षणिक आयाम
इसकी सादगी के कारण लोमुटो की विभाजन विधि को लागू करना आसान हो सकता है। सॉर्टिंग पर जॉन बेंटले के प्रोग्रामिंग पर्ल में एक अच्छा किस्सा है :
"क्विकॉर्ट की अधिकांश चर्चाएं दो दृष्टिकोण सूचकांकों [...] [यानी होरेस] पर आधारित एक विभाजन योजना का उपयोग करती हैं। हालांकि उस योजना का मूल विचार सीधा है, मैंने हमेशा विवरण को मुश्किल पाया है - मैंने एक बार दो दिनों के बेहतर हिस्से को एक छोटे से विभाजन पाश में छिपे हुए बग का पीछा करते हुए बिताया। प्रारंभिक मसौदे के एक पाठक ने शिकायत की कि मानक दो-सूचकांक विधि वास्तव में लोमुटो की तुलना में सरल है और अपनी बात बनाने के लिए कुछ कोड को स्केच किया गया है; दो बग देखने के बाद मैंने देखना बंद कर दिया। "
प्रदर्शन आयाम
व्यावहारिक उपयोग के लिए, कार्यकुशलता के लिए कार्यान्वयन में आसानी का त्याग किया जा सकता है। सैद्धांतिक आधार पर, हम प्रदर्शन की तुलना करने के लिए तत्व तुलना और स्वैप की संख्या निर्धारित कर सकते हैं। इसके अतिरिक्त, वास्तविक चलने का समय अन्य कारकों से प्रभावित होगा, जैसे कैशिंग प्रदर्शन और शाखा की गड़बड़ी।
जैसा कि नीचे दिखाया गया है, एल्गोरिदम स्वैप की संख्या को छोड़कर यादृच्छिक क्रमपरिवर्तन पर बहुत समान है । वहाँ लोमुटो को होरे के रूप में तीन बार चाहिए !
तुलना की संख्या
लंबाई की एक सरणी को विभाजित करने के लिए तुलना का उपयोग करके दोनों तरीकों को लागू किया जा सकता है । यह अनिवार्य रूप से इष्टतम है, क्योंकि हमें यह तय करने के लिए हर तत्व की धुरी से तुलना करने की आवश्यकता है कि इसे कहां रखा जाए।n−1n
स्वैप की संख्या
सरणी में तत्वों के आधार पर दोनों एल्गोरिदम के लिए स्वैप की संख्या यादृच्छिक है। यदि हम यादृच्छिक क्रमपरिवर्तन मानते हैं , अर्थात सभी तत्व अलग-अलग हैं और तत्वों के प्रत्येक क्रमांकन की समान रूप से संभावना है, तो हम स्वैप की अपेक्षित संख्या का विश्लेषण कर सकते हैं ।
जैसा कि केवल सापेक्ष क्रम मायने रखता है, हम मानते हैं कि तत्व संख्या । यह एक तत्व की रैंक और उसके मूल्य के मेल के बाद से चर्चा को आसान बनाता है।1,…,n
लोमुटो की विधि
इंडेक्स वेरिएबल पूरे ऐरे को स्कैन करता है और जब भी हमें कोई तत्व पिवट से छोटा लगता है , हम एक स्वैप करते हैं। तत्वों में से , बिल्कुल वाले से छोटे हैं , इसलिए हमें स्वैप मिलता है यदि धुरी ।jA[j]x1,…,nx−1xx−1x
समग्र अपेक्षा तो सभी पिवोट्स के औसत से होती है। में प्रत्येक मूल्य समान रूप से धुरी बनने की संभावना है (अर्थात् । ), इसलिए हमारे पास है{1,…,n}1n
1n∑x=1n(x−1)=n2−12.
Lomuto की विधि के साथ लंबाई की एक सरणी को विभाजित करने के लिए औसत पर स्वैप ।n
होरे की विधि
यहां, विश्लेषण थोड़ा अधिक पेचीदा है: यहां तक कि पिवट ठीक करने पर , स्वैप की संख्या यादृच्छिक रहती है।x
अधिक सटीक: सूचक और एक दूसरे की ओर तब तक चलते हैं जब तक वे पार नहीं हो जाते, जो हमेशा पर होता है (होरे के विभाजन एल्गोरिथ्म की शुद्धता के द्वारा!)। यह सरणी को प्रभावी रूप से दो भागों में विभाजित करता है: एक बायां भाग जो कि द्वारा स्कैन किया गया है और एक दायां भाग द्वारा स्कैन किया गया है ।ijxij
अब, "गलत" तत्वों की प्रत्येक जोड़ी के लिए एक स्वैप किया जाता है , अर्थात एक बड़ा तत्व ( से बड़ा , इस प्रकार दाएं विभाजन से संबंधित) जो वर्तमान में बाएं भाग में स्थित है और एक छोटा तत्व सही भाग में स्थित है। ध्यान दें कि यह जोड़ी बनाने वाले हमेशा काम करते हैं, यानी दाएं हिस्से में शुरू में छोटे तत्वों की संख्या बाएं हिस्से में बड़े तत्वों की संख्या के बराबर होती है।x
एक दिखा सकता है कि इन जोड़ियों की संख्या अतिशयोक्तिपूर्ण रूप से वितरित की गई है: बड़े तत्वों के लिए हम बेतरतीब ढंग से उनके पदों को खींचते हैं और स्थिति रखते हैं बचा हुआ हिस्सा। तदनुसार, जोड़े की अपेक्षित संख्या है जिसे देखते हुए धुरी ।Hyp(n−1,n−x,x−1)n−xx−1(n−x)(x−1)/(n−1)x
अंत में, हम होरे के विभाजन के लिए स्वैप की समग्र अपेक्षित संख्या प्राप्त करने के लिए सभी धुरी मूल्यों पर फिर से औसत रखते हैं:
1n∑x=1n(n−x)(x−1)n−1=n6−13.
(अधिक विस्तृत विवरण मेरे गुरु की थीसिस में पाया जा सकता है , पृष्ठ 29।)
मेमोरी एक्सेस पैटर्न
दोनों एल्गोरिदम दो बिंदुओं को सरणी में उपयोग करते हैं जो इसे क्रमिक रूप से स्कैन करते हैं । इसलिए दोनों लगभग इष्टतम wrt कैशिंग व्यवहार करते हैं।
समान तत्व और पहले से ही क्रमबद्ध सूची
जैसा कि पहले से ही भटकने वाले तर्क द्वारा उल्लेख किया गया है, एल्गोरिदम का प्रदर्शन उन सूचियों के लिए अधिक भिन्न होता है जो यादृच्छिक क्रमपरिवर्तन नहीं हैं।
पहले से छांटे गए सरणी पर, होरे की विधि कभी भी स्वैप नहीं होती है , क्योंकि कोई गलत जोड़े नहीं हैं (ऊपर देखें), जबकि लोमुटो की विधि अभी भी अपने लगभग स्वैप करती है!n/2
समान तत्वों की उपस्थिति को क्विकॉर्ट में विशेष देखभाल की आवश्यकता होती है। (मैंने स्वयं इस जाल में कदम रखा; मेरे गुरु की थीसिस , पृष्ठ 36, "समय पर अनुकूलन के लिए कथा" के लिए देखें) एक चरम उदाहरण के रूप में विचार करें जो एस से भरा है । इस तरह के एक सरणी पर, होरे की विधि हर जोड़ी तत्वों के लिए एक स्वैप करती है - जो कि होरे के विभाजन के लिए सबसे खराब स्थिति है - लेकिन और हमेशा सरणी के बीच में मिलते हैं। इस प्रकार, हमारे पास इष्टतम विभाजन है और कुल चलने का समय ।0ijO(nlogn)
लोम्यूटो की विधि सभी सरणी पर बहुत अधिक मूर्खतापूर्ण व्यवहार करती है : तुलना हमेशा सच होगी, इसलिए हम हर एक तत्व के लिए एक स्वैप करते हैं ! लेकिन इससे भी बदतर: लूप के बाद, हमारे पास हमेशा , इसलिए हम सबसे खराब स्थिति विभाजन का निरीक्षण करते हैं, जिससे समग्र प्रदर्शन नीचा हो जाता है !0A[j] <= x
i=nΘ(n2)
निष्कर्ष
लोमुटो की विधि सरल और लागू करने में आसान है, लेकिन इसका उपयोग लाइब्रेरी सॉर्टिंग विधि को लागू करने के लिए नहीं किया जाना चाहिए।
A[i+1] <= x
। एक क्रमबद्ध सरणी में (और यथोचित रूप से चुने गए पिवोट्स) होरे लगभग कोई स्वैप नहीं करता है और लोमुटो एक टन करता है (एक बार जे काफी छोटा हो जाता है तो सभीA[j] <= x
।) मुझे क्या याद आ रहा है?