ฉันต้องการจัดเรียงอาร์เรย์ของวัตถุประมาณ 200-300 รายการโดยเรียงตามคีย์เฉพาะและลำดับที่กำหนด (asc / desc) ลำดับของผลลัพธ์ต้องสอดคล้องและคงที่
อัลกอริทึมที่ดีที่สุดที่จะใช้คืออะไรและคุณสามารถให้ตัวอย่างของการใช้งานในจาวาสคริปต์ได้หรือไม่
ขอบคุณ!
ฉันต้องการจัดเรียงอาร์เรย์ของวัตถุประมาณ 200-300 รายการโดยเรียงตามคีย์เฉพาะและลำดับที่กำหนด (asc / desc) ลำดับของผลลัพธ์ต้องสอดคล้องและคงที่
อัลกอริทึมที่ดีที่สุดที่จะใช้คืออะไรและคุณสามารถให้ตัวอย่างของการใช้งานในจาวาสคริปต์ได้หรือไม่
ขอบคุณ!
คำตอบ:
เป็นไปได้ที่จะได้รับการจัดเรียงที่มั่นคงจากฟังก์ชันการเรียงลำดับที่ไม่คงที่
ก่อนจัดเรียงคุณจะได้รับตำแหน่งขององค์ประกอบทั้งหมด ในเงื่อนไขการจัดเรียงของคุณหากทั้งสององค์ประกอบเท่ากันคุณจะจัดเรียงตามตำแหน่ง
ธาดา! คุณมีการจัดเรียงที่มั่นคง
ฉันได้เขียนบทความเกี่ยวกับเรื่องนี้ในบล็อกของฉันหากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับเทคนิคนี้และวิธีการใช้งาน: http://blog.vjeux.com/2010/javascript/javascript-sorting-table.html
เนื่องจากคุณกำลังมองหาสิ่งที่มั่นคงการเรียงลำดับการผสานควรทำ
http://www.stoimen.com/blog/2010/07/02/friday-algorithms-javascript-merge-sort/
รหัสสามารถพบได้ที่เว็บไซต์ด้านบน:
function mergeSort(arr)
{
if (arr.length < 2)
return arr;
var middle = parseInt(arr.length / 2);
var left = arr.slice(0, middle);
var right = arr.slice(middle, arr.length);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right)
{
var result = [];
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
while (left.length)
result.push(left.shift());
while (right.length)
result.push(right.shift());
return result;
}
แก้ไข:
ตามโพสต์นี้ดูเหมือนว่า Array การจัดเรียงในการใช้งานบางอย่างใช้การจัดเรียงแบบผสาน
Array#shift
อาจทำงานในเวลา O (n) และของคุณmerge
ใน O (n * n)
เวอร์ชันที่ค่อนข้างสั้นกว่าของสิ่งเดียวกันโดยใช้คุณสมบัติ ES2017 เช่นฟังก์ชันลูกศรและการทำลายโครงสร้าง:
var stableSort = (arr, compare) => arr
.map((item, index) => ({item, index}))
.sort((a, b) => compare(a.item, b.item) || a.index - b.index)
.map(({item}) => item)
ยอมรับอาร์เรย์อินพุตและเปรียบเทียบฟังก์ชัน:
stableSort([5,6,3,2,1], (a, b) => a - b)
นอกจากนี้ยังส่งคืนอาร์เรย์ใหม่แทนการจัดเรียงแบบแทนที่เช่นฟังก์ชันArray.sort () ในตัว
ถ้าเราใช้input
อาร์เรย์ต่อไปนี้โดยเริ่มต้นโดยweight
:
// sorted by weight
var input = [
{ height: 100, weight: 80 },
{ height: 90, weight: 90 },
{ height: 70, weight: 95 },
{ height: 100, weight: 100 },
{ height: 80, weight: 110 },
{ height: 110, weight: 115 },
{ height: 100, weight: 120 },
{ height: 70, weight: 125 },
{ height: 70, weight: 130 },
{ height: 100, weight: 135 },
{ height: 75, weight: 140 },
{ height: 70, weight: 140 }
]
จากนั้นจัดเรียงโดยheight
ใช้stableSort
:
stableSort(input, (a, b) => a.height - b.height)
ผลลัพธ์ใน:
// Items with the same height are still sorted by weight
// which means they preserved their relative order.
var stable = [
{ height: 70, weight: 95 },
{ height: 70, weight: 125 },
{ height: 70, weight: 130 },
{ height: 70, weight: 140 },
{ height: 75, weight: 140 },
{ height: 80, weight: 110 },
{ height: 90, weight: 90 },
{ height: 100, weight: 80 },
{ height: 100, weight: 100 },
{ height: 100, weight: 120 },
{ height: 100, weight: 135 },
{ height: 110, weight: 115 }
]
อย่างไรก็ตามการจัดเรียงinput
อาร์เรย์เดียวกันโดยใช้บิวท์อินArray.sort()
(ใน Chrome / NodeJS):
input.sort((a, b) => a.height - b.height)
ผลตอบแทน:
var unstable = [
{ height: 70, weight: 140 },
{ height: 70, weight: 95 },
{ height: 70, weight: 125 },
{ height: 70, weight: 130 },
{ height: 75, weight: 140 },
{ height: 80, weight: 110 },
{ height: 90, weight: 90 },
{ height: 100, weight: 100 },
{ height: 100, weight: 80 },
{ height: 100, weight: 135 },
{ height: 100, weight: 120 },
{ height: 110, weight: 115 }
]
Array.prototype.sort
ตอนนี้เสถียรแล้วใน V8 v7.0 / Chrome 70!ก่อนหน้านี้ V8 ใช้ QuickSort ที่ไม่เสถียรสำหรับอาร์เรย์ที่มีองค์ประกอบมากกว่า 10 รายการ ตอนนี้เราใช้อัลกอริทึม TimSort ที่เสถียร
stableSort
ฟังก์ชั่นเป็นทางออกที่ดีจริงๆ!
ฉันรู้ว่าคำถามนี้ได้รับคำตอบมาระยะหนึ่งแล้ว แต่ฉันบังเอิญมีการใช้งานการเรียงลำดับการผสานที่เสถียรที่ดีสำหรับ Array และ jQuery ในคลิปบอร์ดของฉันดังนั้นฉันจะแบ่งปันด้วยความหวังว่าผู้ค้นหาในอนาคตจะพบว่ามีประโยชน์
ช่วยให้คุณระบุฟังก์ชันการเปรียบเทียบของคุณเองเหมือนกับการArray.sort
ใช้งานปกติ
// Add stable merge sort to Array and jQuery prototypes
// Note: We wrap it in a closure so it doesn't pollute the global
// namespace, but we don't put it in $(document).ready, since it's
// not dependent on the DOM
(function() {
// expose to Array and jQuery
Array.prototype.mergeSort = jQuery.fn.mergeSort = mergeSort;
function mergeSort(compare) {
var length = this.length,
middle = Math.floor(length / 2);
if (!compare) {
compare = function(left, right) {
if (left < right)
return -1;
if (left == right)
return 0;
else
return 1;
};
}
if (length < 2)
return this;
return merge(
this.slice(0, middle).mergeSort(compare),
this.slice(middle, length).mergeSort(compare),
compare
);
}
function merge(left, right, compare) {
var result = [];
while (left.length > 0 || right.length > 0) {
if (left.length > 0 && right.length > 0) {
if (compare(left[0], right[0]) <= 0) {
result.push(left[0]);
left = left.slice(1);
}
else {
result.push(right[0]);
right = right.slice(1);
}
}
else if (left.length > 0) {
result.push(left[0]);
left = left.slice(1);
}
else if (right.length > 0) {
result.push(right[0]);
right = right.slice(1);
}
}
return result;
}
})();
var sorted = [
'Finger',
'Sandwich',
'sandwich',
'5 pork rinds',
'a guy named Steve',
'some noodles',
'mops and brooms',
'Potato Chip Brand® chips'
].mergeSort(function(left, right) {
lval = left.toLowerCase();
rval = right.toLowerCase();
console.log(lval, rval);
if (lval < rval)
return -1;
else if (lval == rval)
return 0;
else
return 1;
});
sorted == ["5 pork rinds", "a guy named Steve", "Finger", "mops and brooms", "Potato Chip Brand® chips", "Sandwich", "sandwich", "some noodles"];
array.sort
ดูการทดสอบที่นี่สำหรับทั้งสตริงและจำนวนเต็ม -> jsfiddle.net/QC64j
mergeSort
ไม่ใช่sort
ดังนั้นจึงไม่ได้มีไว้เพื่อทดแทน บางครั้งคุณเพียงแค่ต้องการการเรียงลำดับการผสานที่มั่นคงเช่นเมื่อจัดเรียงตารางตามคอลัมน์
คุณสามารถใช้โพลีฟิลล์ต่อไปนี้เพื่อใช้การจัดเรียงที่เสถียรโดยไม่คำนึงถึงการนำไปใช้งานแบบเนทีฟตามการยืนยันในคำตอบนี้ :
// ECMAScript 5 polyfill
Object.defineProperty(Array.prototype, 'stableSort', {
configurable: true,
writable: true,
value: function stableSort (compareFunction) {
'use strict'
var length = this.length
var entries = Array(length)
var index
// wrap values with initial indices
for (index = 0; index < length; index++) {
entries[index] = [index, this[index]]
}
// sort with fallback based on initial indices
entries.sort(function (a, b) {
var comparison = Number(this(a[1], b[1]))
return comparison || a[0] - b[0]
}.bind(compareFunction))
// re-map original array to stable sorted values
for (index = 0; index < length; index++) {
this[index] = entries[index][1]
}
return this
}
})
// usage
const array = Array(500000).fill().map(() => Number(Math.random().toFixed(4)))
const alwaysEqual = () => 0
const isUnmoved = (value, index) => value === array[index]
// not guaranteed to be stable
console.log('sort() stable?', array
.slice()
.sort(alwaysEqual)
.every(isUnmoved)
)
// guaranteed to be stable
console.log('stableSort() stable?', array
.slice()
.stableSort(alwaysEqual)
.every(isUnmoved)
)
// performance using realistic scenario with unsorted big data
function time(arrayCopy, algorithm, compare) {
var start
var stop
start = performance.now()
algorithm.call(arrayCopy, compare)
stop = performance.now()
return stop - start
}
const ascending = (a, b) => a - b
const msSort = time(array.slice(), Array.prototype.sort, ascending)
const msStableSort = time(array.slice(), Array.prototype.stableSort, ascending)
console.log('sort()', msSort.toFixed(3), 'ms')
console.log('stableSort()', msStableSort.toFixed(3), 'ms')
console.log('sort() / stableSort()', (100 * msSort / msStableSort).toFixed(3) + '%')
การทดสอบประสิทธิภาพที่ดำเนินการข้างต้นstableSort()
ดูเหมือนว่าจะทำงานที่ความเร็วประมาณ 57% ของsort()
Chrome เวอร์ชัน 59-61
การใช้.bind(compareFunction)
ฟังก์ชันที่ไม่ระบุชื่อที่ห่อหุ้มไว้ภายในstableSort()
ช่วยเพิ่มประสิทธิภาพการทำงานสัมพัทธ์จากประมาณ 38% โดยหลีกเลี่ยงการอ้างอิงตามขอบเขตที่ไม่จำเป็นสำหรับการcompareFunction
โทรแต่ละครั้งโดยกำหนดให้กับบริบทแทน
เปลี่ยนตัวดำเนินการ ternary เป็นการลัดวงจรเชิงตรรกะซึ่งมีแนวโน้มที่จะทำงานได้ดีขึ้นโดยเฉลี่ย (ดูเหมือนจะทำให้ประสิทธิภาพแตกต่างกัน 2-3%)
ต่อไปนี้จะจัดเรียงอาร์เรย์ที่ให้มาโดยใช้ฟังก์ชันการเปรียบเทียบที่ให้มาโดยส่งกลับการเปรียบเทียบดัชนีเดิมเมื่อฟังก์ชันเปรียบเทียบส่งคืน 0:
function stableSort(arr, compare) {
var original = arr.slice(0);
arr.sort(function(a, b){
var result = compare(a, b);
return result === 0 ? original.indexOf(a) - original.indexOf(b) : result;
});
return arr;
}
ตัวอย่างด้านล่างจัดเรียงอาร์เรย์ของชื่อตามนามสกุลโดยคงลำดับของนามสกุลที่เท่ากัน:
var names = [
{ surname: "Williams", firstname: "Mary" },
{ surname: "Doe", firstname: "Mary" },
{ surname: "Johnson", firstname: "Alan" },
{ surname: "Doe", firstname: "John" },
{ surname: "White", firstname: "John" },
{ surname: "Doe", firstname: "Sam" }
]
function stableSort(arr, compare) {
var original = arr.slice(0);
arr.sort(function(a, b){
var result = compare(a, b);
return result === 0 ? original.indexOf(a) - original.indexOf(b) : result;
});
return arr;
}
stableSort(names, function(a, b) {
return a.surname > b.surname ? 1 : a.surname < b.surname ? -1 : 0;
})
names.forEach(function(name) {
console.log(name.surname + ', ' + name.firstname);
});
jQuery.expando.split( "" ).sort( ( a, b ) => 0 ).join( "" ) === jQuery.expando
นี่คือการใช้งานที่เสถียร ทำงานโดยใช้การจัดเรียงแบบเนทีฟ แต่ในกรณีที่องค์ประกอบเปรียบเทียบว่าเท่ากันคุณจะทำลายความสัมพันธ์โดยใช้ตำแหน่งดัชนีเดิม
function stableSort(arr, cmpFunc) {
//wrap the arr elements in wrapper objects, so we can associate them with their origional starting index position
var arrOfWrapper = arr.map(function(elem, idx){
return {elem: elem, idx: idx};
});
//sort the wrappers, breaking sorting ties by using their elements orig index position
arrOfWrapper.sort(function(wrapperA, wrapperB){
var cmpDiff = cmpFunc(wrapperA.elem, wrapperB.elem);
return cmpDiff === 0
? wrapperA.idx - wrapperB.idx
: cmpDiff;
});
//unwrap and return the elements
return arrOfWrapper.map(function(wrapper){
return wrapper.elem;
});
}
การทดสอบที่ไม่ละเอียดถี่ถ้วน
var res = stableSort([{a:1, b:4}, {a:1, b:5}], function(a, b){
return a.a - b.a;
});
console.log(res);
คำตอบอื่นพาดพิงถึงเรื่องนี้ แต่ไม่ได้โพสต์ codez
แต่มันไม่ได้อย่างรวดเร็วตามที่ฉันมาตรฐาน ฉันแก้ไขการเรียงลำดับการผสานเพื่อยอมรับฟังก์ชันตัวเปรียบเทียบที่กำหนดเองและมันเร็วกว่ามาก
คุณยังสามารถใช้ Timsort นี่เป็นอัลกอริทึมที่ซับซ้อนมาก (400+ บรรทัดจึงไม่มีซอร์สโค้ดที่นี่) ดังนั้นโปรดดูคำอธิบายของ Wikipediaหรือใช้หนึ่งในการใช้งาน JavaScript ที่มีอยู่:
การใช้ GPL 3การดำเนินการ บรรจุเป็น Array.prototype.timsort ดูเหมือนว่าเป็นการเขียนโค้ด Java ซ้ำทุกประการ
การใช้งานโดเมนสาธารณะหมายถึงการสอนโค้ดตัวอย่างจะแสดงเฉพาะการใช้งานกับจำนวนเต็ม
Timsort เป็นไฮบริดที่ดีที่สุดของการผสานและการเรียงลำดับแบบสุ่มและเป็นอัลกอริธึมการเรียงลำดับเริ่มต้นใน Python และใน Java (1.7+) เป็นอัลกอริทึมที่ซับซ้อนเนื่องจากใช้อัลกอริทึมที่แตกต่างกันสำหรับกรณีพิเศษต่างๆ แต่ผลที่ตามมามันเร็วมากภายใต้สถานการณ์ที่หลากหลาย
การผสานแบบง่าย ๆ เรียงลำดับจากhttp://www.stoimen.com/blog/2010/07/02/friday-algorithms-javascript-merge-sort/
var a = [34, 203, 3, 746, 200, 984, 198, 764, 9];
function mergeSort(arr)
{
if (arr.length < 2)
return arr;
var middle = parseInt(arr.length / 2);
var left = arr.slice(0, middle);
var right = arr.slice(middle, arr.length);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right)
{
var result = [];
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
while (left.length)
result.push(left.shift());
while (right.length)
result.push(right.shift());
return result;
}
console.log(mergeSort(a));
ฉันต้องจัดเรียงอาร์เรย์หลายมิติตามคอลัมน์โดยพลการแล้วตามด้วยอีกคอลัมน์หนึ่ง ฉันใช้ฟังก์ชันนี้เพื่อจัดเรียง:
function sortMDArrayByColumn(ary, sortColumn){
//Adds a sequential number to each row of the array
//This is the part that adds stability to the sort
for(var x=0; x<ary.length; x++){ary[x].index = x;}
ary.sort(function(a,b){
if(a[sortColumn]>b[sortColumn]){return 1;}
if(a[sortColumn]<b[sortColumn]){return -1;}
if(a.index>b.index){
return 1;
}
return -1;
});
}
โปรดสังเกตว่า ary.sort ไม่เคยส่งกลับค่าศูนย์ซึ่งเป็นที่ที่การใช้งานฟังก์ชัน "sort" บางอย่างทำให้การตัดสินใจอาจไม่ถูกต้อง
นี่ค่อนข้างเร็วเกินไป
นี่คือวิธีการที่คุณสามารถขยาย JS วัตถุอาร์เรย์เริ่มต้นด้วยวิธีการต้นแบบการใช้เรียงลำดับผสาน วิธีนี้ช่วยให้สามารถจัดเรียงคีย์เฉพาะ (พารามิเตอร์แรก) และลำดับที่กำหนด ('asc' / 'desc' เป็นพารามิเตอร์ที่สอง)
Array.prototype.mergeSort = function(sortKey, direction){
var unsortedArray = this;
if(unsortedArray.length < 2) return unsortedArray;
var middle = Math.floor(unsortedArray.length/2);
var leftSubArray = unsortedArray.slice(0,middle).mergeSort(sortKey, direction);
var rightSubArray = unsortedArray.slice(middle).mergeSort(sortKey, direction);
var sortedArray = merge(leftSubArray, rightSubArray);
return sortedArray;
function merge(left, right) {
var combined = [];
while(left.length>0 && right.length>0){
var leftValue = (sortKey ? left[0][sortKey] : left[0]);
var rightValue = (sortKey ? right[0][sortKey] : right[0]);
combined.push((direction === 'desc' ? leftValue > rightValue : leftValue < rightValue) ? left.shift() : right.shift())
}
return combined.concat(left.length ? left : right)
}
}
คุณสามารถทดสอบด้วยตัวเองได้โดยวางข้อมูลโค้ดด้านบนลงในคอนโซลของเบราว์เซอร์จากนั้นลอง:
var x = [2,76,23,545,67,-9,12];
x.mergeSort(); //[-9, 2, 12, 23, 67, 76, 545]
x.mergeSort(undefined, 'desc'); //[545, 76, 67, 23, 12, 2, -9]
หรือเรียงลำดับตามฟิลด์เฉพาะในอาร์เรย์ของวัตถุ:
var y = [
{startTime: 100, value: 'cat'},
{startTime: 5, value: 'dog'},
{startTime: 23, value: 'fish'},
{startTime: 288, value: 'pikachu'}
]
y.mergeSort('startTime');
y.mergeSort('startTime', 'desc');
ดังนั้นฉันจึงต้องการการจัดเรียงที่มั่นคงสำหรับแอป React + Redux ของฉันและคำตอบของ Vjeux ที่นี่ช่วยฉันได้ อย่างไรก็ตามโซลูชัน (ทั่วไป) ของฉันดูเหมือนจะแตกต่างจากวิธีอื่น ๆ ที่ฉันเห็นที่นี่ดังนั้นฉันจึงแบ่งปันในกรณีที่ใครก็ตามมีกรณีการใช้งานที่ตรงกัน:
sort()
API ซึ่งฉันสามารถส่งผ่านฟังก์ชันเปรียบเทียบได้วิธีแก้ปัญหาของฉันคือการสร้างอาร์เรย์ที่พิมพ์จากindices
นั้นใช้ฟังก์ชันเปรียบเทียบเพื่อจัดเรียงดัชนีเหล่านี้ตามอาร์เรย์ที่จะจัดเรียง จากนั้นเราสามารถใช้การเรียงลำดับindices
เพื่อจัดเรียงอาร์เรย์เดิมหรือสร้างสำเนาที่เรียงลำดับในครั้งเดียว หากเกิดความสับสนให้คิดในลักษณะนี้ซึ่งโดยปกติคุณจะส่งผ่านฟังก์ชันเปรียบเทียบเช่น:
(a, b) => {
/* some way to compare a and b, returning -1, 0, or 1 */
};
ตอนนี้คุณใช้:
(i, j) => {
let a = arrayToBeSorted[i], b = arrayToBeSorted[j];
/* some way to compare a and b, returning -1 or 1 */
return i - j; // fallback when a == b
}
ความเร็วเป็นสิ่งที่ดี โดยพื้นฐานแล้วอัลกอริธึมการเรียงลำดับในตัวคือบวกสองเส้นตรงในตอนท้ายและอีกหนึ่งชั้นของค่าใช้จ่ายชี้ทิศทาง
ยินดีรับคำติชมเกี่ยวกับแนวทางนี้ นี่คือการใช้งานเต็มรูปแบบของฉัน:
/**
* - `array`: array to be sorted
* - `comparator`: closure that expects indices `i` and `j`, and then
* compares `array[i]` to `array[j]` in some way. To force stability,
* end with `i - j` as the last "comparison".
*
* Example:
* ```
* let array = [{n: 1, s: "b"}, {n: 1, s: "a"}, {n:0, s: "a"}];
* const comparator = (i, j) => {
* const ni = array[i].n, nj = array[j].n;
* return ni < nj ? -1 :
* ni > nj ? 1 :
* i - j;
* };
* stableSortInPlace(array, comparator);
* // ==> [{n:0, s: "a"}, {n:1, s: "b"}, {n:1, s: "a"}]
* ```
*/
function stableSortInPlace(array, comparator) {
return sortFromIndices(array, findIndices(array, comparator));
}
function stableSortedCopy(array, comparator){
let indices = findIndices(array, comparator);
let sortedArray = [];
for (let i = 0; i < array.length; i++){
sortedArray.push(array[indices[i]]);
}
return sortedArray;
}
function findIndices(array, comparator){
// Assumes we don't have to worry about sorting more than
// 4 billion elements; if you know the upper bounds of your
// input you could replace it with a smaller typed array
let indices = new Uint32Array(array.length);
for (let i = 0; i < indices.length; i++) {
indices[i] = i;
}
// after sorting, `indices[i]` gives the index from where
// `array[i]` should take the value from, so to sort
// move the value at at `array[indices[i]]` to `array[i]`
return indices.sort(comparator);
}
// If I'm not mistaken this is O(2n) - each value is moved
// only once (not counting the vacancy temporaries), and
// we also walk through the whole array once more to check
// for each cycle.
function sortFromIndices(array, indices) {
// there might be multiple cycles, so we must
// walk through the whole array to check.
for (let k = 0; k < array.length; k++) {
// advance until we find a value in
// the "wrong" position
if (k !== indices[k]) {
// create vacancy to use "half-swaps" trick,
// props to Andrei Alexandrescu
let v0 = array[k];
let i = k;
let j = indices[k];
while (j !== k) {
// half-swap next value
array[i] = array[j];
// array[i] now contains the value it should have,
// so we update indices[i] to reflect this
indices[i] = i;
// go to next index
i = j;
j = indices[j];
}
// put original array[k] back in
// and update indices
array[i] = v0;
indices[i] = i;
}
}
return array;
}
ฉันรู้ว่ามีคำตอบมากมาย ฉันแค่อยากจะโพสต์การใช้ TS ฉบับย่อสำหรับทุกคนที่มาที่นี่เพื่อค้นหาสิ่งนั้น
export function stableSort<T>( array: T[], compareFn: ( a: T, b: T ) => number ): T[] {
const indices = array.map( ( x: T, i: number ) => ( { element: x, index: i } ) );
return indices.sort( ( a, b ) => {
const order = compareFn( a.element, b.element );
return order === 0 ? a.index - b.index : order;
} ).map( x => x.element );
}
เมธอดไม่ทำงานในตำแหน่งอีกต่อไปเช่นเดียวกับการจัดเรียงแบบเนทีฟ ฉันยังต้องการชี้ให้เห็นว่ามันไม่ได้มีประสิทธิภาพมากที่สุด เพิ่มสองลูปของคำสั่ง O (n) แม้ว่าการเรียงลำดับจะเป็นไปได้มากที่สุด O (n log (n)) ดังนั้นจึงน้อยกว่านั้น
โซลูชันบางอย่างที่กล่าวถึงมีประสิทธิภาพมากกว่าคิดว่าอาจใช้รหัสน้อยกว่าและใช้ภายในด้วย Array.prototype.sort
ด้วย
(สำหรับโซลูชัน Javascript ให้ลบทุกประเภทออก)
ตามที่บล็อก v8 devและcaniuse.com Array.sort
มีความเสถียรแล้วตามข้อกำหนดในเบราว์เซอร์สมัยใหม่ดังนั้นคุณไม่จำเป็นต้องม้วนโซลูชันของคุณเอง ข้อยกเว้นเดียวที่ฉันเห็นคือ Edge ซึ่งเร็ว ๆ นี้ควรย้ายไปที่โครเมียมและรองรับเช่นกัน
function sort(data){
var result=[];
var array = data;
const array2=data;
const len=array2.length;
for(var i=0;i<=len-1;i++){
var min = Math.min.apply(Math,array)
result.push(min);
var index=array.indexOf(min)
array.splice(index,1);
}
return result;
}
sort([9,8,5,7,9,3,9,243,4,5,6,3,4,2,4,7,4,9,55,66,33,66]);
การเรียงลำดับการนับเร็วกว่าการเรียงลำดับการรวม (ดำเนินการในเวลา O (n)) และมีไว้สำหรับใช้กับจำนวนเต็ม
Math.counting_sort = function (m) {
var i
var j
var k
var step
var start
var Output
var hash
k = m.length
Output = new Array ()
hash = new Array ()
// start at lowest possible value of m
start = 0
step = 1
// hash all values
i = 0
while ( i < k ) {
var _m = m[i]
hash [_m] = _m
i = i + 1
}
i = 0
j = start
// find all elements within x
while ( i < k ) {
while ( j != hash[j] ) {
j = j + step
}
Output [i] = j
i = i + 1
j = j + step
}
return Output
}
ตัวอย่าง:
var uArray = new Array ()<br/>
var sArray = new Array ()<br/><br/>
uArray = [ 10,1,9,2,8,3,7,4,6,5 ]<br/>
sArray = Math.counting_sort ( uArray ) // returns a sorted array
array [3, 1, 3]
hashes [undefined, 1, undefined, 3]
ไป เราได้รับค่าที่ไม่ได้กำหนดสองค่าในขณะที่อัลกอริทึมคาดว่าจะมีสามค่า