जावास्क्रिप्ट Array#sort()
फ़ंक्शन किस एल्गोरिथ्म का उपयोग करता है? मैं समझता हूं कि विभिन्न प्रकार के प्रदर्शन करने के लिए यह सभी तरह के तर्क और कार्य कर सकता है, मुझे बस दिलचस्पी है कि एल्गोरिथ्म में वेनिला सॉर्ट का उपयोग होता है।
जावास्क्रिप्ट Array#sort()
फ़ंक्शन किस एल्गोरिथ्म का उपयोग करता है? मैं समझता हूं कि विभिन्न प्रकार के प्रदर्शन करने के लिए यह सभी तरह के तर्क और कार्य कर सकता है, मुझे बस दिलचस्पी है कि एल्गोरिथ्म में वेनिला सॉर्ट का उपयोग होता है।
जवाबों:
यदि आप इस बग 224128 को देखते हैं , तो ऐसा प्रतीत होता है कि मर्जर्ट का उपयोग मोज़िला द्वारा किया जा रहा है।
मैंने अभी-अभी WebKit (Chrome, Safari…) स्रोत पर एक नज़र डाली है । सरणी के प्रकार के आधार पर, विभिन्न प्रकार के तरीकों का उपयोग किया जाता है:
संख्यात्मक सरणियों (या आदिम प्रकार के सरणियों) को C ++ मानक लाइब्रेरी फ़ंक्शन का उपयोग करके सॉर्ट किया जाता है std::qsort
जो क्विकॉर्ट्स (आमतौर पर इंट्रोसर्ट ) के कुछ भिन्नता को लागू करता है ।
नॉन-न्यूमेरिक प्रकार के समवर्ती सरणियों को कड़ा कर दिया जाता है और मर्जों का उपयोग करके सॉर्ट किया जाता है, यदि उपलब्ध हो (एक स्थिर सॉर्टिंग प्राप्त करने के लिए) या qsort
यदि कोई मर्ज सॉर्ट उपलब्ध नहीं है।
अन्य प्रकारों के लिए (गैर-सन्निहित सरणियों और संभवतः साहचर्य सरणियों के लिए) WebKit चयन प्रकार (जिसे वे "न्यूनतम" सॉर्ट कहते हैं ) का उपयोग करता है या, कुछ मामलों में, यह AVL ट्री के माध्यम से सॉर्ट करता है। दुर्भाग्य से, यहाँ प्रलेखन अस्पष्ट है, इसलिए आपको कोड पथ का पता लगाने के लिए वास्तव में यह देखना होगा कि किस प्रकार की विधि का उपयोग किया जाता है।
और फिर इस टिप्पणी की तरह रत्न भी हैं :
// FIXME: Since we sort by string value, a fast algorithm might be to use a
// radix sort. That would be O(N) rather than O(N log N).
- चलो बस उम्मीद करते हैं कि जो कोई भी वास्तव में "फिक्स" करता है, उसे इस टिप्पणी के लेखक की तुलना में स्पर्शोन्मुख रनटाइम की बेहतर समझ है, और यह महसूस करता है कि मूलांक सॉर्ट में ओ (एन) की तुलना में थोड़ा अधिक जटिल रनटाइम विवरण है।
(मूल उत्तर में त्रुटि को इंगित करने के लिए phsource के लिए धन्यवाद।)
जेएस के लिए किसी विशिष्ट छंटाई वाले अल्गोरथिम का उपयोग करने के लिए कोई मसौदा आवश्यकता नहीं है। जैसा कि कई लोगों ने यहां बताया है, मोज़िला मर्ज सॉर्ट का उपयोग करता है। हालांकि, क्रोम के v8 स्रोत कोड में, आज तक, यह छोटे सरणियों के लिए क्विकॉर्ट और इंसर्शनसॉर्ट का उपयोग करता है।
लाइन्स से 807 - 891
var QuickSort = function QuickSort(a, from, to) {
var third_index = 0;
while (true) {
// Insertion sort is faster for short arrays.
if (to - from <= 10) {
InsertionSort(a, from, to);
return;
}
if (to - from > 1000) {
third_index = GetThirdIndex(a, from, to);
} else {
third_index = from + ((to - from) >> 1);
}
// Find a pivot as the median of first, last and middle element.
var v0 = a[from];
var v1 = a[to - 1];
var v2 = a[third_index];
var c01 = comparefn(v0, v1);
if (c01 > 0) {
// v1 < v0, so swap them.
var tmp = v0;
v0 = v1;
v1 = tmp;
} // v0 <= v1.
var c02 = comparefn(v0, v2);
if (c02 >= 0) {
// v2 <= v0 <= v1.
var tmp = v0;
v0 = v2;
v2 = v1;
v1 = tmp;
} else {
// v0 <= v1 && v0 < v2
var c12 = comparefn(v1, v2);
if (c12 > 0) {
// v0 <= v2 < v1
var tmp = v1;
v1 = v2;
v2 = tmp;
}
}
// v0 <= v1 <= v2
a[from] = v0;
a[to - 1] = v2;
var pivot = v1;
var low_end = from + 1; // Upper bound of elements lower than pivot.
var high_start = to - 1; // Lower bound of elements greater than pivot.
a[third_index] = a[low_end];
a[low_end] = pivot;
// From low_end to i are elements equal to pivot.
// From i to high_start are elements that haven't been compared yet.
partition: for (var i = low_end + 1; i < high_start; i++) {
var element = a[i];
var order = comparefn(element, pivot);
if (order < 0) {
a[i] = a[low_end];
a[low_end] = element;
low_end++;
} else if (order > 0) {
do {
high_start--;
if (high_start == i) break partition;
var top_elem = a[high_start];
order = comparefn(top_elem, pivot);
} while (order > 0);
a[i] = a[high_start];
a[high_start] = element;
if (order < 0) {
element = a[i];
a[i] = a[low_end];
a[low_end] = element;
low_end++;
}
}
}
if (to - high_start < low_end - from) {
QuickSort(a, high_start, to);
to = low_end;
} else {
QuickSort(a, from, low_end);
from = high_start;
}
}
};
अपडेट 2018 के अनुसार V8 टिमशॉर्ट का उपयोग करता है, धन्यवाद @सेलवेल। स्रोत
ECMAscript मानक निर्दिष्ट नहीं करता है कि किस प्रकार के एल्गोरिदम का उपयोग किया जाना है। दरअसल, विभिन्न ब्राउज़रों में अलग-अलग तरह के एल्गोरिदम होते हैं। उदाहरण के लिए, मोज़िला / फ़ायरफ़ॉक्स का सॉर्ट () शब्द की छंटाई के समय स्थिर नहीं है (शब्द की सॉर्टिंग अर्थ में)। IE का सॉर्ट () स्थिर है।
Array.sort
; इस प्रश्न को देखें ।
मुझे लगता है कि इस बात पर निर्भर करेगा कि आप किस ब्राउज़र कार्यान्वयन को संदर्भित कर रहे हैं।
प्रत्येक ब्राउज़र प्रकार में इसका स्वयं का जावास्क्रिप्ट इंजन कार्यान्वयन होता है, इसलिए यह निर्भर करता है। आप मोज़िला और वेबकिट / खटमल के लिए अलग-अलग कार्यान्वयन के लिए स्रोत कोड की जांच कर सकते हैं।
IE, हालांकि स्रोत बंद है, इसलिए आपको Microsoft में किसी से पूछना पड़ सकता है।
V8 v7.0 / Chrome 70 के रूप में, V8 TimSort , पायथन के सॉर्टिंग एल्गोरिथ्म का उपयोग करता है। क्रोम 70 को 13 सितंबर, 2018 को रिलीज़ किया गया था।
इस परिवर्तन के विवरण के लिए V8 देव ब्लॉग पर पोस्ट देखें । आप स्रोत कोड या पैच 1186801 भी पढ़ सकते हैं ।
JavaScript का Array.sort () फ़ंक्शन में सरणी तत्वों के डेटाटाइप के आधार पर सर्वोत्तम सॉर्टिंग एल्गोरिथ्म (QuickSort, MergeSort, आदि) का चयन करने के लिए आंतरिक तंत्र है।
इसे त्वरित रूप से आज़माएं:
function sort(arr, compareFn = (a, b) => a <= b) {
if (!arr instanceof Array || arr.length === 0) {
return arr;
}
if (typeof compareFn !== 'function') {
throw new Error('compareFn is not a function!');
}
const partition = (arr, low, high) => {
const pivot = arr[low];
while (low < high) {
while (low < high && compareFn(pivot, arr[high])) {
--high;
}
arr[low] = arr[high];
while (low < high && compareFn(arr[low], pivot)) {
++low;
}
arr[high] = arr[low];
}
arr[low] = pivot;
return low;
};
const quickSort = (arr, low, high) => {
if (low < high) {
let pivot = partition(arr, low, high);
quickSort(arr, low, pivot - 1);
quickSort(arr, pivot + 1, high);
}
return arr;
};
return quickSort(arr, 0, arr.length - 1);
}