स्मूथसॉर्ट: Difference between revisions

From Vigyanwiki
(Created page with "{{Short description|Comparison-based sorting algorithm}} {{Infobox Algorithm |class=Sorting algorithm |image=File:Smoothsort.gif||alt=An animation depicting smoothsort's...")
 
No edit summary
Line 12: Line 12:
}}
}}


[[कंप्यूटर विज्ञान]] में, स्मूथसॉर्ट एक तुलनात्मक सॉर्ट|तुलना-आधारित [[छँटाई एल्गोरिथ्म]] है। [[ढेर बनाएं और छांटें]] का एक प्रकार, इसका आविष्कार और प्रकाशन 1981 में [[एडवर्ड डिज्क्स्ट्रा]] द्वारा किया गया था।<ref name=EWD-796a>{{Cite EWD|796a|16 Aug 1981|Smoothsort – an alternative to sorting in situ|quote=One can also raise the question why I have not chosen as available stretch lengths: ... 63 31 15 7 3 1 which seems attractive since each stretch can then be viewed as the postorder traversal of a balanced binary tree. In addition, the recurrence relation would be simpler.  But I know why I chose the Leonardo numbers:}}</ref> हीपसॉर्ट की तरह, स्मूथसॉर्ट एक [[इन-प्लेस एल्गोरिदम]] है जिसकी ऊपरी सीमा होती है {{math|''[[Big O notation|O]]''(''n'' log&nbsp;''n'')}},{{r|hertel}} लेकिन यह एक [[स्थिर प्रकार]] नहीं है।<ref>{{cite web
 
[[कंप्यूटर विज्ञान]] में, '''स्मूथसॉर्ट''' एक तुलना-आधारित क्रमबद्ध करने वाला एल्गोरिदम है। हीपसॉर्ट का एक वेरिएंट होता है, जिसे 1981 में [[एडवर्ड डिज्क्स्ट्रा]] ने आविष्कार और प्रकाशित किया था।<ref name="EWD-796a">{{Cite EWD|796a|16 Aug 1981|Smoothsort – an alternative to sorting in situ|quote=One can also raise the question why I have not chosen as available stretch lengths: ... 63 31 15 7 3 1 which seems attractive since each stretch can then be viewed as the postorder traversal of a balanced binary tree. In addition, the recurrence relation would be simpler.  But I know why I chose the Leonardo numbers:}}</ref> स्मूथसॉर्ट भी हीपसॉर्ट की तरह एक स्थानीय एल्गोरिदम है जिसका अपर सीमा {{math|''[[Big O notation|O]]''(''n'' log&nbsp;''n'')}},{{r|hertel}} होता है, परंतु यह [[स्थिर प्रकार|स्थिर क्रमबद्ध]] करने वाला नहीं है।<ref>{{cite web
  |title=Fastest In-Place Stable Sort
  |title=Fastest In-Place Stable Sort
  |first=Craig |last=Brown
  |first=Craig |last=Brown
Line 18: Line 19:
  |url=http://www.codeproject.com/Articles/26048/Fastest-In-Place-Stable-Sort
  |url=http://www.codeproject.com/Articles/26048/Fastest-In-Place-Stable-Sort
  |publisher=[[Code Project]]
  |publisher=[[Code Project]]
}}{{self-published source|date=January 2016}}</ref>{{self-published inline|date=January 2016}}<ref>{{cite web
}}{{self-published source|date=January 2016}}</ref><ref>{{cite web
  |title=Where is the smoothsort algorithm used?
  |title=Where is the smoothsort algorithm used?
  |first=David |last=Eisenstat
  |first=David |last=Eisenstat
Line 26: Line 27:
  |access-date=2020-10-28
  |access-date=2020-10-28
  |quote=Smoothsort is not stable, and stability is often more desirable than in-place in practice
  |quote=Smoothsort is not stable, and stability is often more desirable than in-place in practice
}}</ref> स्मूथसॉर्ट का लाभ यह है कि यह करीब आता है {{math|''O''(''n'')}} समय यदि [[अनुकूली प्रकार]] है, जबकि हीपसॉर्ट औसत है {{math|''O''(''n'' log&nbsp;''n'')}} प्रारंभिक क्रमबद्ध स्थिति की परवाह किए बिना।
}}</ref> स्मूथसॉर्ट का लाभ यह है कि यदि प्रारंभिक रूप से सॉर्टेड होने वाली इनपुट हो, तो यह {{math|''O''(''n'')}} समय के पास आता है, जबकि हीपसॉर्ट का औसत {{math|''O''(''n'' log&nbsp;''n'')}} होता है, चाहे आदि सॉर्ट हो या न हो।


==अवलोकन==
==अवलोकन==
हीप्सॉर्ट की तरह, स्मूथसॉर्ट इनपुट को [[प्राथमिकता कतार]] में व्यवस्थित करता है और फिर बार-बार अधिकतम निकालता है। हीप्सोर्ट की तरह, प्राथमिकता कतार एक [[अंतर्निहित डेटा संरचना]] हीप डेटा संरचना (एक हीप (डेटा संरचना)-आदेशित अंतर्निहित [[ द्विआधारी वृक्ष ]]) है, जो सरणी के एक उपसर्ग पर कब्जा कर लेती है। प्रत्येक निष्कर्षण उपसर्ग को सिकोड़ता है और निकाले गए तत्व को बढ़ते हुए क्रमबद्ध प्रत्यय में जोड़ता है। जब उपसर्ग सिकुड़कर शून्य हो जाता है, तो सरणी पूरी तरह से क्रमबद्ध हो जाती है।
स्मूथसॉर्ट भी हीपसॉर्ट की तरह इनपुट को एक [[प्राथमिकता कतार]] (प्रायोरिटी कतार) में संगठित करता है और पुनः बार-बार अधिकतम को निकालता है। हीपसॉर्ट की तरह हीपसॉर्ट के लिए प्राथमिकता कतार एक निहित हीप डेटा संरचना (एक हीप-क्रमित निहित [[ द्विआधारी वृक्ष |द्विआधारी वृक्ष]] ) होती है, जो सरणी का एक प्रीफिक्स (प्राथमिकता कतार की संक्षेप में) में स्थान रोकती है। प्रत्येक निकालने से प्रीफिक्स न्यूनतम हो जाता है और निकाले गए तत्व को एक बढ़ती हुई क्रमबद्ध साफ़ समाप्ति में जोड़ता है। जब प्रीफिक्स को शून्य न्यूनतम हो जाता है, तो सरणी पूरी तरह से क्रमबद्ध हो जाती है।


हीपसॉर्ट पेड़ के शीर्ष-नीचे चौड़ाई-प्रथम ट्रैवर्सल का उपयोग करके बाइनरी ट्री को सरणी में मैप करता है; सरणी पेड़ की जड़ से शुरू होती है, फिर उसके दो बच्चे, फिर चार पोते-पोतियाँ, और इसी तरह। प्रत्येक तत्व की पेड़ की जड़ के नीचे एक अच्छी तरह से परिभाषित गहराई होती है, और जड़ को छोड़कर प्रत्येक तत्व का मूल तत्व सरणी में पहले होता है। हालाँकि, पत्तियों के ऊपर इसकी ऊँचाई सरणी के आकार पर निर्भर करती है। इसका नुकसान यह है कि प्रत्येक तत्व को सॉर्टिंग प्रक्रिया के हिस्से के रूप में स्थानांतरित किया जाना चाहिए: इसे अपने अंतिम स्थान पर ले जाने से पहले रूट से गुजरना होगा।
हीपसॉर्ट बाइनरी [[ द्विआधारी वृक्ष |वृक्ष]] को सरणी में मानचित्र करता है जहां वृक्ष का ऊपर से नीचे ब्रेड्थ-फर्स्ट ट्रेवर्सल का उपयोग किया जाता है। सरणी में पहले मूल तत्व आता है, पुनः उसके दो बच्चे, पुनः चार पोते, और ऐसे ही आगे भी होते हैं। हर तत्व का जड़ से मान निर्धारित होता है वृक्ष की जड़ से नीचे के गहराई में, और मूल तत्व को छोड़कर हर तत्व की संदर्भ सरणी में पिछले तत्व के पश्चात आती है। यद्यपि, पत्तियों से ऊपर उठने की ऊंचाई सरणी के आकार पर निर्भर करती है। इसका दोष यह है कि क्रमबद्ध करने की प्रक्रिया के हिस्से के रूप में हर तत्व को ले जाना होता है: इसे अंतिम स्थान पर ले जाने से पहले यह मूल तत्व के माध्यम से गुजरना होता है।


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


अधिक औपचारिक रूप से, हर स्थिति {{mvar|i}} एक अद्वितीय उपवृक्ष की जड़ है, जिसके नोड्स एक सन्निहित अंतराल पर होते हैं जो समाप्त होता है {{mvar|i}}. सरणी का एक प्रारंभिक उपसर्ग (संपूर्ण सरणी सहित), एक उपवृक्ष के अनुरूप एक ऐसा अंतराल हो सकता है, लेकिन सामान्य तौर पर यह ऐसे कई क्रमिक उपवृक्ष अंतरालों के संघ के रूप में विघटित होता है, जिसे डिज्क्स्ट्रा स्ट्रेच कहते हैं। माता-पिता के बिना कोई भी उपवृक्ष (अर्थात ऐसी स्थिति में निहित है जिसका माता-पिता विचाराधीन उपसर्ग से परे है) उस अंतराल के अपघटन में एक खिंचाव देता है, इसलिए यह अपघटन अद्वितीय है। जब एक नया नोड उपसर्ग में जोड़ा जाता है, तो दो मामलों में से एक होता है: या तो स्थिति एक पत्ती है और अपघटन में लंबाई 1 का खिंचाव जोड़ती है, या यह अंतिम दो हिस्सों के साथ जुड़ती है, उनकी संबंधित जड़ों का जनक बन जाती है, इस प्रकार दो हिस्सों को एक नए हिस्से से बदल दिया जाता है जिसमें उनका मिलन और नई (रूट) स्थिति शामिल होती है।
औपचारिक रूप से कहें तो, हर स्थान i एक अद्वितीय उपवृक्ष की जड़ होता है, जिसके नोड i तक की एक संयुक्त अवधि को धारण करते हैं। सरणी का एक प्रारंभिक प्रीफिक्स (संपूर्ण सरणी सहित), एक ऐसी अवधि हो सकती है जो किसी उपवृक्ष के लिए एक उपवृक्ष अवधि के संयोजन के रूप में होती है, परंतु सामान्य रूप से इसे कई निरंतर उपवृक्ष अवधियों के एक संयोजन के रूप में विघटित किया जाता है, जिन्हें डाइजक्स्ट्रा "स्ट्रेच" कहते हैं। किसी माता-पिता के बिना कोई भी उपवृक्ष (अर्थात् पथरूप में निर्धारित स्थान की जड़ से निर्मित) प्रारंभिक प्रीफिक्स के विघटन में एक स्ट्रेच देता है, जिसके कारण यह विघटन अद्वितीय होता है। जब प्रीफिक्स में एक नवीन नोड जोड़ा जाता है, तो दो स्थितियाँ हो सकती हैं: या वह स्थान एक पत्ती होता है और विघटन में एक लंबाई 1 का स्ट्रेच जोड़ता है, या वह आखिरी दो स्ट्रेच के साथ मिलकर, उनके संबंधित जड़ों के माता-पिता बनकर, इस प्रकार उन्हें दो स्ट्रेचों को एक नवीन स्ट्रेच के रूप में परिवर्तित करता है, जिसमें उनके संयोजन का संयोजन और नया (रूट) स्थान समावेश होता है।


दिज्क्स्ट्रा ने नोट किया{{r|EWD-796a}} कि स्पष्ट नियम यह होगा कि स्ट्रेच को केवल तभी संयोजित किया जाए जब उनका आकार समान हो, उस स्थिति में सभी उपवृक्ष आकार के सही बाइनरी पेड़ होंगे {{math|2<sup>''k''</sup>−1}}. हालाँकि, उन्होंने एक अलग नियम चुना, जो पेड़ों के अधिक संभावित आकार देता है। इसमें वही एसिम्प्टोटिक विश्लेषण है,{{r|hertel}} लेकिन प्रत्येक अंतराल को कवर करने के लिए कम विस्तार की आवश्यकता के कारण दक्षता में एक छोटा स्थिर कारक प्राप्त होता है।
डाइजक्स्ट्रा ने दर्शाया{{r|EWD-796a}} कि स्पष्ट नियम होगा कि स्ट्रेच केवल तभी मिलाए जाएंगे जब उनका आकार समान हो, जिसके परिणामस्वरूप सभी उपवृक्ष पूर्ण द्विआधारी वृक्ष होंगे जिनका आकार {{math|2<sup>''k''</sup>−1}} होता है। यद्यपि, उन्होंने एक पृथक नियम चुना है, जिससे अधिक संभावित वृक्ष आकार मिलते हैं। इसमें असिम्प्टोटिक दक्षता में कोई परिवर्तित नहीं होता है,{{r|hertel}} परंतु प्रत्येक अवधि को कवर करने के लिए न्यूनतम संख्या में स्ट्रेच की आवश्यकता होने के कारण, यह दक्षता में छोटे संख्यात्मक कारक का लाभ प्राप्त करता है।


डिज्क्स्ट्रा जिस नियम का उपयोग करता है वह यह है कि अंतिम दो हिस्सों को संयोजित किया जाता है यदि और केवल तभी जब उनका आकार लगातार [[लियोनार्डो संख्या]] हो {{math|''L''(''i''+1)}} और {{math|''L''(''i'')}} (उस क्रम में), किन संख्याओं को पुनरावर्ती रूप से परिभाषित किया गया है, [[फाइबोनैचि संख्या]]ओं के समान ही, जैसे:
डिज्क्स्ट्रा जिस नियम का उपयोग करता है वह यह है कि अंतिम दो हिस्सों को संयोजित किया जाता है यदि और केवल तभी जब उनका आकार निरंतर [[लियोनार्डो संख्या]] हो {{math|''L''(''i''+1)}} और {{math|''L''(''i'')}} (उस क्रम में), किन संख्याओं को पुनरावर्ती रूप से परिभाषित किया गया है, [[फाइबोनैचि संख्या]]ओं के समान ही है, जैसे:
* {{math|1=''L''(0) = ''L''(1) = 1}}
* {{math|1=''L''(0) = ''L''(1) = 1}}
* {{math|1=''L''(''k''+2) = ''L''(''k''+1) + ''L''(''k'') + 1}}
* {{math|1=''L''(''k''+2) = ''L''(''k''+1) + ''L''(''k'') + 1}}
परिणामस्वरूप, किसी भी उपवृक्ष का आकार लियोनार्डो संख्या है। खिंचाव के आकार का क्रम पहले विघटित होता है {{mvar|n}}पद, किसी के लिए {{mvar|n}}, लालची तरीके से पाया जा सकता है: पहला आकार सबसे बड़ा लियोनार्डो संख्या से अधिक नहीं है {{mvar|n}}, और शेष (यदि कोई हो) पुनरावर्ती रूप से विघटित हो जाता है। स्ट्रेच के आकार कम हो रहे हैं, संभवतः दो अंतिम आकार 1 को छोड़कर, और संभवतः अंतिम दो आकारों को छोड़कर क्रमिक लियोनार्डो संख्याओं से परहेज किया जा रहा है।
परिणामस्वरूप, किसी भी उपवृक्ष का आकार लियोनार्डो संख्या है। खिंचाव के आकार का क्रम पहले विघटित होता है {{mvar|n}}पद, किसी के लिए {{mvar|n}}, लालची विधियों से पाया जा सकता है: पहला आकार सबसे बड़ा लियोनार्डो संख्या से अधिक नहीं है {{mvar|n}}, और शेष (यदि कोई हो) पुनरावर्ती रूप से विघटित हो जाता है। स्ट्रेच के आकार न्यूनतम हो रहे हैं, संभवतः दो अंतिम आकार 1 को छोड़कर, और संभवतः अंतिम दो आकारों को छोड़कर क्रमिक लियोनार्डो संख्याओं से परहेज किया जा रहा है।


प्रत्येक खंड ढेर-क्रम वाले पेड़ होने के अलावा, पेड़ों की जड़ों को क्रमबद्ध क्रम में बनाए रखा जाता है। यह प्रभावी रूप से प्रत्येक रूट में एक तीसरा बच्चा (जिसे दिज्क्स्ट्रा सौतेला बेटा कहता है) जोड़ता है और इसे पिछले रूट से जोड़ता है। यह सभी पेड़ों को एक साथ एक वैश्विक ढेर में जोड़ता है। अंत में वैश्विक अधिकतम के साथ।
इस परिणामस्वरूप, किसी भी उपवृक्ष का आकार एक लियोनार्डो संख्या होता है। किसी भी nपद के लिए, प्रथम nपद स्थानों को विघटित करने वाली स्ट्रेचों के आकार का अनुक्रम लोभी विधियों से प्राप्त किया जा सकता है: पहला आकार n पद से छोटा लियोनार्डो संख्या है, और शेषांश (यदि कोई हो) को पुनर्निर्भर रूप से विघटित किया जाता है। स्ट्रेचों के आकार घटते हैं, सख्त रूप से केवल दो अंतिम आकार 1 के लिए छोड़ते हैं, और यह सुनिश्चित करते हैं कि दो आकारों के पड़ोसी लियोनार्डो संख्याओं के अतिरिक्त कोई लगातार संख्याएं नहीं होती हैं, केवल शेष दो आकारों के लिए ऐसा हो सकता है।


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


छँटाई के पहले (ढेर बढ़ने) चरण में, सरणी के एक बड़े प्रारंभिक भाग को पुनर्गठित किया जाता है ताकि इसके प्रत्येक विस्तार के लिए उपवृक्ष अधिकतम-ढेर हो: किसी भी गैर-पत्ती स्थिति में प्रविष्टि कम से कम उतनी बड़ी हो उन पदों पर प्रविष्टियाँ जो उसके बच्चे हैं। इसके अलावा, सभी जड़ें कम से कम उनके सौतेले बेटे जितनी बड़ी होती हैं।
यद्यपि, प्रत्येक नोड के स्टेपसन का स्थान स्थिर होता है, परंतु यह संपर्क केवल वृक्ष की जड़ों के लिए होता है, इसका अर्थ है कि जब वृक्षों को मिलाया जाता है, तब संपर्क हटा दिया जाता है। यह साधारित बच्चों से पृथक है, जो तब तक संपर्क में होते हैं जब तक माता-पिता उपस्थित होता हैं।


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


व्यावहारिक कार्यान्वयन के लिए अक्सर लियोनार्डो संख्याओं की गणना करने की आवश्यकता होती है {{math|''L''(''k'')}}. डिज्क्स्ट्रा चतुर कोड प्रदान करता है जो आवश्यक समय पर आवश्यक मूल्यों की कुशलतापूर्वक गणना करने के लिए निश्चित संख्या में पूर्णांक चर का उपयोग करता है। वैकल्पिक रूप से, यदि कोई परिमित सीमा है {{mvar|N}} क्रमबद्ध किए जाने वाले सरणियों के आकार पर, लियोनार्डो संख्याओं की एक पूर्व-गणना की गई तालिका को संग्रहीत किया जा सकता है {{math|''O''(log&nbsp;''N'')}} अंतरिक्ष।
दूसरे चरण में, अधिकतम नोड को सरणी के अंत से पृथक कर दिया जाता है, और ढेर अपरिवर्तनीय को उसके बच्चों के मध्य पुनः से स्थापित किया जाता है।
 
व्यावहारिक कार्यान्वयन में प्रायः लियोनार्डो संख्याओं {{math|''L''(''k'')}} की गणना की जरूरत होती है। डाइजक्स्ट्रा ने चतुर कोड प्रदान किया है जिसमें एक स्थायी संख्या चरोंवाले पूर्णांकीय मानों का उपयोग करके आवश्यक मानों की प्रभावी गणना की जाती है। वैकल्पिक रूप से, यदि सॉर्ट करने के लिए एरे का आकार {{mvar|N}} का एक सीमित बाउंड होता है, तो {{math|''O''(log&nbsp;''N'')}} अंतरिक्ष में पूर्व-गणित लियोनार्डो संख्या की एक पूर्वनिर्धारित सारणी संग्रहीत की जा सकती है।


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


स्मूथसॉर्ट और बाइनरी मैक्स-हीप के बीच अंतर यह है कि प्रत्येक स्ट्रेच की जड़ को तीसरे स्टेपसन के संबंध में क्रमबद्ध किया जाना चाहिए: पूर्ववर्ती स्ट्रेच की जड़। तो सिफ्ट-डाउन प्रक्रिया चार-तरफा तुलनाओं (रूट नोड और तीन बच्चों) की एक श्रृंखला के साथ शुरू होती है जब तक कि स्टेप्सन अधिकतम तत्व नहीं होता है, फिर तीन-तरफा तुलनाओं की एक श्रृंखला (रूट प्लस दो बच्चे) रूट तक नोड को अपना अंतिम घर मिल जाता है और अपरिवर्तनीय पुनः स्थापित हो जाते हैं।
स्मूथसॉर्ट और एक बाइनरी मैक्स-हीप के मध्य अंतर यह है कि प्रत्येक स्ट्रेच की रूट को तीसरे "स्टेपसन" के संबंध में क्रमबद्ध किया जाना चाहिए: पिछले स्ट्रेच की रूट। इसलिए, सिफ्ट-डाउन प्रक्रिया चार-तरफी तुलनाएं  के साथ प्रारंभ होती है जब तक स्टेपसन अधिकतम तत्व नहीं होता है, और पुनः तीन-तरफी तुलनाएं के साथ जब तक रूट नोड अपना अंतिम गृह नहीं मिलता है और नियम स्थापित किए जाते हैं।


प्रत्येक पेड़ एक बाइनरी ट्री है#बाइनरी ट्री के प्रकार: प्रत्येक नोड में दो बच्चे होते हैं या एक भी नहीं। एक बच्चे के विशेष मामले से निपटने की कोई आवश्यकता नहीं है जो एक मानक अंतर्निहित [[बाइनरी ढेर]] में होता है। (लेकिन सौतेले बेटे के लिंक का विशेष मामला इस बचत की भरपाई करता है।)
प्रत्येक वृक्ष पूर्ण बाइनरी वृक्ष है: प्रत्येक नोड के दो बच्चे होते हैं या कोई नहीं होते। साधारित निहित बाइनरी हीप में जो एक बच्चा होता है, उसे संबोधित करने की कोई आवश्यकता नहीं होती है।  


क्योंकि वहाँ हैं {{math|''O''(log&nbsp;''n'')}} विस्तार, जिनमें से प्रत्येक गहराई का एक वृक्ष है {{math|''O''(log&nbsp;''n'')}}, प्रत्येक सिफ्टिंग-डाउन ऑपरेशन को करने का समय निर्धारित है {{math|''O''(log&nbsp;''n'')}}.
क्योंकि यहाँ {{math|''O''(log&nbsp;''n'')}} असंख्य स्ट्रेचेस हैं, जिनमें प्रत्येक एक वृक्ष {{math|''O''(log&nbsp;''n'')}} की गहराई का होता है, इसलिए प्रत्येक सिफ्ट-डाउन आपरेशन को करने का समय {{math|''O''(log&nbsp;''n'')}} से बंधा हुआ है।


===दाईं ओर एक तत्व को शामिल करके ढेर क्षेत्र को बढ़ाना===
===दाईं ओर एक तत्व को सम्मलित करके ढेर क्षेत्र को बढ़ाना===
जब एक अतिरिक्त तत्व को स्ट्रेच के अनुक्रम (असंयुक्त ढेर संरचनाओं की सूची) में शामिल करने पर विचार किया जाता है, तो यह या तो एक नया एक-तत्व स्ट्रेच बनाता है, या यह दोनों जड़ों के माता-पिता बनकर दो सबसे दाहिने स्ट्रेच को जोड़ता है और एक नया स्ट्रेच बनाता है। जो क्रम में दोनों को प्रतिस्थापित करता है। दोनों में से क्या होता है यह केवल वर्तमान में मौजूद हिस्सों के आकार पर निर्भर करता है (और अंततः केवल जोड़े गए तत्व के सूचकांक पर); डिज्क्स्ट्रा ने निर्धारित किया कि स्ट्रेच को तभी संयोजित किया जाता है जब उनके आकार हों {{math|''L''(''k''+1)}} और {{math|''L''(''k'')}} कुछ के लिए {{mvar|k}}, यानी, लगातार लियोनार्डो संख्या; नए खंड का आकार होगा {{math|''L''(''k''+2)}}.
जब एक अतिरिक्त तत्व को स्ट्रेच के अनुक्रम में सम्मलित करने पर विचार किया जाता है, तो यह या तो एक नया एक-तत्व स्ट्रेच बनाता है, या यह दोनों जड़ों के माता-पिता बनकर दो सबसे दाहिने स्ट्रेच को जोड़ता है और एक नया स्ट्रेच बनाता है। जो क्रम में दोनों को प्रतिस्थापित करता है। दोनों में से क्या होता है यह केवल वर्तमान में उपस्थित हिस्सों के आकार पर निर्भर करता है ,डाइक्स्ट्रा ने निर्धारित किया कि स्ट्रेच केवल तभी जोड़े जाएंगे जब उनके आकार {{math|''L''(''k''+1)}} और {{math|''L''(''k'')}} हों, अर्थात, क्रमशः लियोनार्डो नंबर्स; नया स्ट्रेच आकार {{math|''L''(''k''+2)}}.होगा।


किसी भी स्थिति में, नए तत्व को ढेर संरचना में उसके सही स्थान पर स्थानांतरित किया जाना चाहिए। भले ही नया नोड एक-तत्व खिंचाव है, फिर भी इसे पिछले खिंचाव की जड़ के सापेक्ष क्रमबद्ध किया जाना चाहिए।
दोनों यद्यपि, नए तत्व को आपको सही स्थान पर नीचे स्थानांतरित करना होता है। यदि नया नोड एक-तत्व स्ट्रेच है, तो उसे फिर भी पिछले स्ट्रेच के रूट के संबंध में क्रमबद्ध किया जाना चाहिए।


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


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


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


क्योंकि एक पूर्ण बाइनरी ट्री में सभी नोड्स में से आधे पत्ते होते हैं, यह प्रति नोड औसतन एक सिफ्ट-डाउन ऑपरेशन करता है।
क्योंकि पूर्ण द्विआधारिक वृक्ष में आधी संख्या के सभी नोड पत्ते होते हैं, इससे प्रति नोड औसतन एक सिफ्ट-डाउन ऑपरेशन कार्यान्वित होता है।


====अनुकूलन====
====अनुकूलन====
यह पहले से ही ज्ञात है कि नई उजागर जड़ें अपने सामान्य बच्चों के संबंध में सही ढंग से क्रमबद्ध हैं; यह केवल उनके सौतेले बेटों से संबंधित आदेश है जो प्रश्न में है। इसलिए, ढेर को सिकोड़ते समय, नीचे छानने के पहले चरण को सौतेले बेटे के साथ तुलना करके सरल बनाया जा सकता है। यदि कोई अदला-बदली होती है, तो अगले चरणों में पूर्ण चार-तरफ़ा तुलना करनी होगी।
पहली बार सिफ्ट-डाउन करते समय, नए उज्ज्वलित रूट्स सामान्य बच्चों के संबंध में सही क्रम में होते हैं; इसके अलावा, केवल उनके स्टेपसन्स के संबंध में क्रम विचार में है। इसलिए, हीप को छोटा करते समय, सिफ्ट-डाउन के पहले कदम को स्टेपसन के साथ एकल तुलना के रूप में सरलित किया जा सकता है। यदि स्वैप होता है, तो आगामी कदम पूर्ण चार तरह की तुलना करनी होगी।


==विश्लेषण==
==विश्लेषण==
स्मूथसॉर्ट लेता है {{math|''O''(''n'')}} एक निर्दिष्ट सरणी को संसाधित करने का समय, {{math|''O''(''n'' log&nbsp; ''n'')}} सबसे खराब स्थिति में, और कई लगभग-क्रमबद्ध इनपुट पर लगभग-रैखिक प्रदर्शन प्राप्त करता है। हालाँकि, यह सभी लगभग-क्रमबद्ध अनुक्रमों को बेहतर ढंग से संभाल नहीं पाता है। अन-सॉर्टेडनेस (सूचकांकों के जोड़े की संख्या) के माप के रूप में व्युत्क्रमों की गिनती का उपयोग करना {{mvar|i}} और {{mvar|j}} साथ {{math|''i'' < ''j''}} और {{math|''A''[''i''] > ''A''[''j'']}}; यादृच्छिक रूप से क्रमबद्ध इनपुट के लिए यह लगभग है {{math|''n''<sup>2</sup>/4}}), के साथ संभावित इनपुट अनुक्रम हैं {{math|''O''(''n'' log&nbsp;''n'')}} व्युत्क्रम जो इसे लेने का कारण बनते हैं {{math|Ω(''n'' log&nbsp;''n'')}} समय, जबकि अन्य अनुकूली सॉर्ट एल्गोरिदम इन मामलों को हल कर सकते हैं {{math|''O''(''n'' log&nbsp;log&nbsp;''n'')}} समय।<ref name="hertel">{{cite journal
स्मूथसॉर्ट लेता है {{math|''O''(''n'')}} एक निर्दिष्ट सरणी को संसाधित करने का समय, {{math|''O''(''n'' log&nbsp; ''n'')}} सबसे खराब स्थिति में, और कई लगभग-क्रमबद्ध इनपुट पर लगभग-रैखिक प्रदर्शन प्राप्त करता है। यद्यपि, यह सभी लगभग-क्रमबद्ध अनुक्रमों को बेहतर ढंग से संभाल नहीं पाता है। अन-सॉर्टेडनेस (सूचकांकों के जोड़े की संख्या) के माप के रूप में व्युत्क्रमों की गिनती का उपयोग करना {{mvar|i}} और {{mvar|j}} साथ {{math|''i'' < ''j''}} और {{math|''A''[''i''] > ''A''[''j'']}}; यादृच्छिक रूप से क्रमबद्ध इनपुट के लिए यह लगभग है {{math|''n''<sup>2</sup>/4}}), के साथ संभावित इनपुट अनुक्रम हैं {{math|''O''(''n'' log&nbsp;''n'')}} व्युत्क्रम जो इसे लेने का कारण बनते हैं {{math|Ω(''n'' log&nbsp;''n'')}} समय, जबकि अन्य अनुकूली सॉर्ट एल्गोरिदम इन परिस्थिति को हल कर सकते हैं {{math|''O''(''n'' log&nbsp;log&nbsp;''n'')}} समय।<ref name="hertel">{{cite journal
  |last=Hertel |first=Stefan
  |last=Hertel |first=Stefan
  |title=Smoothsort's behavior on presorted sequences
  |title=Smoothsort's behavior on presorted sequences
Line 94: Line 95:
  |doi=10.1016/0020-0190(83)90116-3
  |doi=10.1016/0020-0190(83)90116-3
}}</ref>
}}</ref>
स्मूथसॉर्ट एल्गोरिदम को लियोनार्डो ढेर के सभी पेड़ों के आकार को स्मृति में रखने में सक्षम होना चाहिए। चूँकि उन्हें क्रम के अनुसार क्रमबद्ध किया जाता है और सभी ऑर्डर अलग-अलग होते हैं, यह आमतौर पर [[बिट वेक्टर]] का उपयोग करके किया जाता है जो दर्शाता है कि कौन से ऑर्डर मौजूद हैं। इसके अलावा, चूँकि सबसे बड़ा ऑर्डर अधिकतम है {{math|''O''(log&nbsp;''n'')}}, इन बिट्स को एन्कोड किया जा सकता है {{math|''O''(1)}} मशीन शब्द, एक [[ट्रांसडिकोटोमस मशीन मॉडल]] मानते हुए।
स्मूथसॉर्ट एल्गोरिदम को लियोनार्डो ढेर के सभी पेड़ों के आकार को स्मृति में रखने में सक्षम होना चाहिए। चूँकि उन्हें क्रम के अनुसार क्रमबद्ध किया जाता है और सभी ऑर्डर पृथक-पृथक होते हैं, यह आमतौर पर [[बिट वेक्टर]] का उपयोग करके किया जाता है जो दर्शाता है कि कौन से ऑर्डर उपस्थित हैं। इसके अलावा, चूँकि सबसे बड़ा ऑर्डर अधिकतम है {{math|''O''(log&nbsp;''n'')}}, इन बिट्स को एन्कोड किया जा सकता है {{math|''O''(1)}} मशीन शब्द, एक [[ट्रांसडिकोटोमस मशीन मॉडल]] मानते हुए।


ध्यान दें कि {{math|''O''(1)}} मशीनी शब्द एक मशीनी शब्द के समान नहीं हैं। एक 32-बिट वेक्टर केवल इससे कम आकार के लिए पर्याप्त होगा {{math|1=''L''(32) = 7049155}}. एक 64-बिट वेक्टर इससे कम आकार के लिए उपयुक्त होगा {{math|1=''L''(64) = 34335360355129 ≈ 2<sup>45</sup>}}. सामान्य तौर पर, इसमें लगता है {{math|1/log<sub>2</sub>(''[[Golden ratio|φ]]'') ≈ 1.44}} आकार के प्रति बिट वेक्टर के बिट्स।
ध्यान दें कि {{math|''O''(1)}} मशीनी शब्द एक मशीनी शब्द के समान नहीं हैं। एक 32-बिट वेक्टर केवल इससे न्यूनतम आकार के लिए पर्याप्त होगा {{math|1=''L''(32) = 7049155}}. एक 64-बिट वेक्टर इससे न्यूनतम आकार के लिए उपयुक्त होगा {{math|1=''L''(64) = 34335360355129 ≈ 2<sup>45</sup>}}. सामान्य तौर पर, इसमें लगता है {{math|1/log<sub>2</sub>(''[[Golden ratio|φ]]'') ≈ 1.44}} आकार के प्रति बिट वेक्टर के बिट्स।


==चिनार प्रकार==
==चिनार प्रकार==
Line 106: Line 107:
  |volume=39 |issue=5 |pages=269&ndash;276 |date=13 September 1991
  |volume=39 |issue=5 |pages=269&ndash;276 |date=13 September 1991
  |doi=10.1016/0020-0190(91)90027-F
  |doi=10.1016/0020-0190(91)90027-F
}}</ref> डच [[पोल्डर]]ों में अक्सर देखे जाने वाले घटते आकार के पेड़ों की पंक्तियों के नाम पर, यह उन इनपुटों के लिए स्मूथसॉर्ट की तुलना में कम तुलना करता है जो अधिकतर सॉर्ट नहीं किए जाते हैं, लेकिन सॉर्ट किए गए इनपुट के लिए रैखिक समय प्राप्त नहीं कर सकते हैं।
}}</ref> डच [[पोल्डर]]ों में प्रायः देखे जाने वाले घटते आकार के पेड़ों की पंक्तियों के नाम पर, यह उन इनपुटों के लिए स्मूथसॉर्ट की तुलना में न्यूनतम तुलना करता है जो अधिकतर सॉर्ट नहीं किए जाते हैं, परंतु सॉर्ट किए गए इनपुट के लिए रैखिक समय प्राप्त नहीं कर सकते हैं।


चिनार की छंटाई द्वारा किया गया महत्वपूर्ण परिवर्तन यह है कि विभिन्न पेड़ों की जड़ों को क्रमबद्ध क्रम में नहीं रखा जाता है; उन्हें एक ही ढेर में बांधने वाली कोई सौतेली कड़ियाँ नहीं हैं। इसके बजाय, हर बार जब दूसरे चरण में ढेर सिकुड़ जाता है, तो अधिकतम प्रविष्टि खोजने के लिए जड़ों की खोज की जाती है।
चिनार की छंटाई द्वारा किया गया महत्वपूर्ण परिवर्तन यह है कि विभिन्न पेड़ों की जड़ों को क्रमबद्ध क्रम में नहीं रखा जाता है; उन्हें एक ही ढेर में बांधने वाली कोई सौतेली कड़ियाँ नहीं हैं। इसके बजाय, हर बार जब दूसरे चरण में ढेर सिकुड़ जाता है, तो अधिकतम प्रविष्टि खोजने के लिए जड़ों की खोज की जाती है।
Line 112: Line 113:
क्योंकि वहाँ हैं {{mvar|n}} सिकुड़ते चरण, जिनमें से प्रत्येक को खोजना होगा {{math|''O''(log&nbsp;''n'')}} अधिकतम के लिए पेड़ की जड़ें, चिनार की किस्म के लिए सबसे अच्छा रन टाइम है  {{math|''O''(''n'' log&nbsp;''n'')}}.
क्योंकि वहाँ हैं {{mvar|n}} सिकुड़ते चरण, जिनमें से प्रत्येक को खोजना होगा {{math|''O''(log&nbsp;''n'')}} अधिकतम के लिए पेड़ की जड़ें, चिनार की किस्म के लिए सबसे अच्छा रन टाइम है  {{math|''O''(''n'' log&nbsp;''n'')}}.


लेखक आगे सरलीकरण प्रदान करने के लिए लियोनार्डो पेड़ों के बजाय सही बाइनरी पेड़ों का उपयोग करने का भी सुझाव देते हैं, लेकिन यह एक कम महत्वपूर्ण परिवर्तन है।
लेखक आगे सरलीकरण प्रदान करने के लिए लियोनार्डो पेड़ों के बजाय सही बाइनरी पेड़ों का उपयोग करने का भी सुझाव देते हैं, परंतु यह एक न्यूनतम महत्वपूर्ण परिवर्तन है।


उसी संरचना को पोस्ट-ऑर्डर हीप नाम के तहत सामान्य प्रयोजन प्राथमिकता कतार के रूप में प्रस्तावित किया गया है,<ref>{{cite conference
उसी संरचना को पोस्ट-ऑर्डर हीप नाम के तहत सामान्य प्रयोजन प्राथमिकता कतार के रूप में प्रस्तावित किया गया है,<ref>{{cite conference
Line 143: Line 144:


==बाहरी संबंध==
==बाहरी संबंध==
* [https://www.enterag.ch/hartwig/order/smoothsort.pdf Commented transcription of EWD796a, 16-Aug-1981]
* [https://www.enterag.ch/hartwig/order/smoothsort.pdf Commenपदted tranपदscriptionपदof EWD796a, 16-Aug-1981]
* [https://www.keithschwarz.com/smoothsort/ Detailed modern explanation of Smoothsort]
* [https://www.keithschwarz.com/smoothsort/ Detailed modernपदexplanपदationपदof Smoothsort]
* [[wikibooks:Algorithm Implementation/Sorting/Smoothsort]]
* [[wikibooks:Algorithm Implementation/Sorting/Smoothsort|wikibooks:Algorithm Implemenपदtationपद/Sortinपदg/Smoothsort]]
* [https://github.com/Morwenn/poplar-heap Description and example implementation of Poplar heap]
* [https://github.com/Morwenn/poplar-heap Descriptionपदanपदd example implemenपदtationपदof Poplar heap]
* {{cite journal
* {{cite journal
  |title=On the Nested Heap Structure in Smoothsort
  |title=On the Nested Heap Structure in Smoothsort

Revision as of 10:41, 4 July 2023

स्मूथसॉर्ट
An animation depicting smoothsort's operation, showing the heap being built and then disassembled,
Smoothsort operating on an array which is mostly in order. The bars across the top show the tree structure.
ClassSorting algorithm
Data structureArray
Worst-case performanceO(n log n)
Best-case performanceO(n)
Average performanceO(n log n)
Worst-case space complexityO(n) total, O(1) auxiliary


कंप्यूटर विज्ञान में, स्मूथसॉर्ट एक तुलना-आधारित क्रमबद्ध करने वाला एल्गोरिदम है। हीपसॉर्ट का एक वेरिएंट होता है, जिसे 1981 में एडवर्ड डिज्क्स्ट्रा ने आविष्कार और प्रकाशित किया था।[1] स्मूथसॉर्ट भी हीपसॉर्ट की तरह एक स्थानीय एल्गोरिदम है जिसका अपर सीमा O(n log n),[2] होता है, परंतु यह स्थिर क्रमबद्ध करने वाला नहीं है।[3][4] स्मूथसॉर्ट का लाभ यह है कि यदि प्रारंभिक रूप से सॉर्टेड होने वाली इनपुट हो, तो यह O(n) समय के पास आता है, जबकि हीपसॉर्ट का औसत O(n log n) होता है, चाहे आदि सॉर्ट हो या न हो।

अवलोकन

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

हीपसॉर्ट बाइनरी वृक्ष को सरणी में मानचित्र करता है जहां वृक्ष का ऊपर से नीचे ब्रेड्थ-फर्स्ट ट्रेवर्सल का उपयोग किया जाता है। सरणी में पहले मूल तत्व आता है, पुनः उसके दो बच्चे, पुनः चार पोते, और ऐसे ही आगे भी होते हैं। हर तत्व का जड़ से मान निर्धारित होता है वृक्ष की जड़ से नीचे के गहराई में, और मूल तत्व को छोड़कर हर तत्व की संदर्भ सरणी में पिछले तत्व के पश्चात आती है। यद्यपि, पत्तियों से ऊपर उठने की ऊंचाई सरणी के आकार पर निर्भर करती है। इसका दोष यह है कि क्रमबद्ध करने की प्रक्रिया के हिस्से के रूप में हर तत्व को ले जाना होता है: इसे अंतिम स्थान पर ले जाने से पहले यह मूल तत्व के माध्यम से गुजरना होता है।

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

औपचारिक रूप से कहें तो, हर स्थान i एक अद्वितीय उपवृक्ष की जड़ होता है, जिसके नोड i तक की एक संयुक्त अवधि को धारण करते हैं। सरणी का एक प्रारंभिक प्रीफिक्स (संपूर्ण सरणी सहित), एक ऐसी अवधि हो सकती है जो किसी उपवृक्ष के लिए एक उपवृक्ष अवधि के संयोजन के रूप में होती है, परंतु सामान्य रूप से इसे कई निरंतर उपवृक्ष अवधियों के एक संयोजन के रूप में विघटित किया जाता है, जिन्हें डाइजक्स्ट्रा "स्ट्रेच" कहते हैं। किसी माता-पिता के बिना कोई भी उपवृक्ष (अर्थात् पथरूप में निर्धारित स्थान की जड़ से निर्मित) प्रारंभिक प्रीफिक्स के विघटन में एक स्ट्रेच देता है, जिसके कारण यह विघटन अद्वितीय होता है। जब प्रीफिक्स में एक नवीन नोड जोड़ा जाता है, तो दो स्थितियाँ हो सकती हैं: या वह स्थान एक पत्ती होता है और विघटन में एक लंबाई 1 का स्ट्रेच जोड़ता है, या वह आखिरी दो स्ट्रेच के साथ मिलकर, उनके संबंधित जड़ों के माता-पिता बनकर, इस प्रकार उन्हें दो स्ट्रेचों को एक नवीन स्ट्रेच के रूप में परिवर्तित करता है, जिसमें उनके संयोजन का संयोजन और नया (रूट) स्थान समावेश होता है।

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

डिज्क्स्ट्रा जिस नियम का उपयोग करता है वह यह है कि अंतिम दो हिस्सों को संयोजित किया जाता है यदि और केवल तभी जब उनका आकार निरंतर लियोनार्डो संख्या हो L(i+1) और L(i) (उस क्रम में), किन संख्याओं को पुनरावर्ती रूप से परिभाषित किया गया है, फाइबोनैचि संख्याओं के समान ही है, जैसे:

  • L(0) = L(1) = 1
  • L(k+2) = L(k+1) + L(k) + 1

परिणामस्वरूप, किसी भी उपवृक्ष का आकार लियोनार्डो संख्या है। खिंचाव के आकार का क्रम पहले विघटित होता है nपद, किसी के लिए n, लालची विधियों से पाया जा सकता है: पहला आकार सबसे बड़ा लियोनार्डो संख्या से अधिक नहीं है n, और शेष (यदि कोई हो) पुनरावर्ती रूप से विघटित हो जाता है। स्ट्रेच के आकार न्यूनतम हो रहे हैं, संभवतः दो अंतिम आकार 1 को छोड़कर, और संभवतः अंतिम दो आकारों को छोड़कर क्रमिक लियोनार्डो संख्याओं से परहेज किया जा रहा है।

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

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

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

सॉर्टिंग की पहली (हीप बढ़ाने वाली) चरण में, एक बढ़ते हुए विस्तार के साथ एक प्रारंभिक हिस्सा को पुनर्व्यवस्थित किया जाता है क्योंकी प्रत्येक स्ट्रेच के लिए उसके उपवृक्ष हीप हो: किसी भी गैर-पत्ता स्थिति में, किसी भी गैर-पत्ता स्थिति पर विद्यमान प्रवेश न्यूनतम से न्यूनतम उसके बच्चों की स्थितियों के प्रवेश से न्यूनतम होता है। इसके अतिरिक्त, सभी रूट्स उनके स्टेपसन्स से न्यूनतम से न्यूनतम होते हैं।

दूसरे चरण में, अधिकतम नोड को सरणी के अंत से पृथक कर दिया जाता है, और ढेर अपरिवर्तनीय को उसके बच्चों के मध्य पुनः से स्थापित किया जाता है।

व्यावहारिक कार्यान्वयन में प्रायः लियोनार्डो संख्याओं L(k) की गणना की जरूरत होती है। डाइजक्स्ट्रा ने चतुर कोड प्रदान किया है जिसमें एक स्थायी संख्या चरोंवाले पूर्णांकीय मानों का उपयोग करके आवश्यक मानों की प्रभावी गणना की जाती है। वैकल्पिक रूप से, यदि सॉर्ट करने के लिए एरे का आकार N का एक सीमित बाउंड होता है, तो O(log N) अंतरिक्ष में पूर्व-गणित लियोनार्डो संख्या की एक पूर्वनिर्धारित सारणी संग्रहीत की जा सकती है।

संचालन

जब श्रेणी-ऑफ-हीप संरचना के विकास की दृष्टि से तकनीकी क्रिया के दो चरण एक-दूसरे के विपरीत होते हैं, तब वे एक मूल साधन का उपयोग करके कार्यान्वित किए जाते हैं, जो एक बाइनरी मैक्स-हीप में "सिफ्ट डाउन" आपरेशन के समकक्ष है।

छानना

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

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

प्रत्येक वृक्ष पूर्ण बाइनरी वृक्ष है: प्रत्येक नोड के दो बच्चे होते हैं या कोई नहीं होते। साधारित निहित बाइनरी हीप में जो एक बच्चा होता है, उसे संबोधित करने की कोई आवश्यकता नहीं होती है।

क्योंकि यहाँ O(log n) असंख्य स्ट्रेचेस हैं, जिनमें प्रत्येक एक वृक्ष O(log n) की गहराई का होता है, इसलिए प्रत्येक सिफ्ट-डाउन आपरेशन को करने का समय O(log n) से बंधा हुआ है।

दाईं ओर एक तत्व को सम्मलित करके ढेर क्षेत्र को बढ़ाना

जब एक अतिरिक्त तत्व को स्ट्रेच के अनुक्रम में सम्मलित करने पर विचार किया जाता है, तो यह या तो एक नया एक-तत्व स्ट्रेच बनाता है, या यह दोनों जड़ों के माता-पिता बनकर दो सबसे दाहिने स्ट्रेच को जोड़ता है और एक नया स्ट्रेच बनाता है। जो क्रम में दोनों को प्रतिस्थापित करता है। दोनों में से क्या होता है यह केवल वर्तमान में उपस्थित हिस्सों के आकार पर निर्भर करता है ,डाइक्स्ट्रा ने निर्धारित किया कि स्ट्रेच केवल तभी जोड़े जाएंगे जब उनके आकार L(k+1) और L(k) हों, अर्थात, क्रमशः लियोनार्डो नंबर्स; नया स्ट्रेच आकार L(k+2).होगा।

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

अनुकूलन

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

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

सबसे दाहिने तत्व को पृथक करके ढेर क्षेत्र को छोटा करना

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

क्योंकि पूर्ण द्विआधारिक वृक्ष में आधी संख्या के सभी नोड पत्ते होते हैं, इससे प्रति नोड औसतन एक सिफ्ट-डाउन ऑपरेशन कार्यान्वित होता है।

अनुकूलन

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

विश्लेषण

स्मूथसॉर्ट लेता है O(n) एक निर्दिष्ट सरणी को संसाधित करने का समय, O(n log  n) सबसे खराब स्थिति में, और कई लगभग-क्रमबद्ध इनपुट पर लगभग-रैखिक प्रदर्शन प्राप्त करता है। यद्यपि, यह सभी लगभग-क्रमबद्ध अनुक्रमों को बेहतर ढंग से संभाल नहीं पाता है। अन-सॉर्टेडनेस (सूचकांकों के जोड़े की संख्या) के माप के रूप में व्युत्क्रमों की गिनती का उपयोग करना i और j साथ i < j और A[i] > A[j]; यादृच्छिक रूप से क्रमबद्ध इनपुट के लिए यह लगभग है n2/4), के साथ संभावित इनपुट अनुक्रम हैं O(n log n) व्युत्क्रम जो इसे लेने का कारण बनते हैं Ω(n log n) समय, जबकि अन्य अनुकूली सॉर्ट एल्गोरिदम इन परिस्थिति को हल कर सकते हैं O(n log log n) समय।[2] स्मूथसॉर्ट एल्गोरिदम को लियोनार्डो ढेर के सभी पेड़ों के आकार को स्मृति में रखने में सक्षम होना चाहिए। चूँकि उन्हें क्रम के अनुसार क्रमबद्ध किया जाता है और सभी ऑर्डर पृथक-पृथक होते हैं, यह आमतौर पर बिट वेक्टर का उपयोग करके किया जाता है जो दर्शाता है कि कौन से ऑर्डर उपस्थित हैं। इसके अलावा, चूँकि सबसे बड़ा ऑर्डर अधिकतम है O(log n), इन बिट्स को एन्कोड किया जा सकता है O(1) मशीन शब्द, एक ट्रांसडिकोटोमस मशीन मॉडल मानते हुए।

ध्यान दें कि O(1) मशीनी शब्द एक मशीनी शब्द के समान नहीं हैं। एक 32-बिट वेक्टर केवल इससे न्यूनतम आकार के लिए पर्याप्त होगा L(32) = 7049155. एक 64-बिट वेक्टर इससे न्यूनतम आकार के लिए उपयुक्त होगा L(64) = 34335360355129 ≈ 245. सामान्य तौर पर, इसमें लगता है 1/log2(φ) ≈ 1.44 आकार के प्रति बिट वेक्टर के बिट्स।

चिनार प्रकार

स्मूथसॉर्ट से प्रेरित एक सरल एल्गोरिदम पॉपलर सॉर्ट है।[5] डच पोल्डरों में प्रायः देखे जाने वाले घटते आकार के पेड़ों की पंक्तियों के नाम पर, यह उन इनपुटों के लिए स्मूथसॉर्ट की तुलना में न्यूनतम तुलना करता है जो अधिकतर सॉर्ट नहीं किए जाते हैं, परंतु सॉर्ट किए गए इनपुट के लिए रैखिक समय प्राप्त नहीं कर सकते हैं।

चिनार की छंटाई द्वारा किया गया महत्वपूर्ण परिवर्तन यह है कि विभिन्न पेड़ों की जड़ों को क्रमबद्ध क्रम में नहीं रखा जाता है; उन्हें एक ही ढेर में बांधने वाली कोई सौतेली कड़ियाँ नहीं हैं। इसके बजाय, हर बार जब दूसरे चरण में ढेर सिकुड़ जाता है, तो अधिकतम प्रविष्टि खोजने के लिए जड़ों की खोज की जाती है।

क्योंकि वहाँ हैं n सिकुड़ते चरण, जिनमें से प्रत्येक को खोजना होगा O(log n) अधिकतम के लिए पेड़ की जड़ें, चिनार की किस्म के लिए सबसे अच्छा रन टाइम है O(n log n).

लेखक आगे सरलीकरण प्रदान करने के लिए लियोनार्डो पेड़ों के बजाय सही बाइनरी पेड़ों का उपयोग करने का भी सुझाव देते हैं, परंतु यह एक न्यूनतम महत्वपूर्ण परिवर्तन है।

उसी संरचना को पोस्ट-ऑर्डर हीप नाम के तहत सामान्य प्रयोजन प्राथमिकता कतार के रूप में प्रस्तावित किया गया है,[6] को प्राप्त करने O(1) एक अंतर्निहित द्विपद ढेर की तुलना में सरल संरचना में परिशोधित विश्लेषण प्रविष्टि समय।

अनुप्रयोग

माँसपेशियाँ सी लाइब्रेरी इसके कार्यान्वयन के लिए स्मूथसॉर्ट का उपयोग करती है qsort().[7][8]


संदर्भ

  1. 1.0 1.1 Dijkstra, Edsger W. 16 Aug 1981 (EWD-796a) (PDF). E.W. Dijkstra Archive. Center for American History, University of Texas at Austin. One can also raise the question why I have not chosen as available stretch lengths: ... 63 31 15 7 3 1 which seems attractive since each stretch can then be viewed as the postorder traversal of a balanced binary tree. In addition, the recurrence relation would be simpler. But I know why I chose the Leonardo numbers: (transcription)
  2. 2.0 2.1 2.2 Hertel, Stefan (13 May 1983). "Smoothsort's behavior on presorted sequences" (PDF). Information Processing Letters. 16 (4): 165–170. doi:10.1016/0020-0190(83)90116-3.
  3. Brown, Craig (21 Jan 2013). "Fastest In-Place Stable Sort". Code Project.[self-published source]
  4. Eisenstat, David (13 September 2020). "Where is the smoothsort algorithm used?". Stack Overflow. Retrieved 2020-10-28. Smoothsort is not stable, and stability is often more desirable than in-place in practice
  5. Bron, Coenraad; Hesselink, Wim H. (13 September 1991). "Smoothsort revisited". Information Processing Letters. 39 (5): 269–276. doi:10.1016/0020-0190(91)90027-F.
  6. Harvey, Nicholas J. A.; Zatloukal, Kevin (26–28 May 2004). The Post-Order Heap. Third International Conference on Fun with Algorithms (FUN 2004). Elba, Italy.
  7. Felker, Rich (30 April 2013). "How do different languages implement sorting in their standard libraries?". Stack Overflow. Retrieved 2020-10-28.
  8. Ochs, Valentin; Felker, Rich (11 August 2017). "src/stdlib/qsort.c". musl - an implementation of the standard library for Linux-based systems. Retrieved 2021-01-26.


बाहरी संबंध