JavaScript的算法";排序();作用

JavaScript的算法";排序();作用,javascript,algorithm,sorting,Javascript,Algorithm,Sorting,最近,当我使用JavaScript“sort()”函数时,我发现其中一个函数不能正确地对数字进行排序。要对数字进行排序,必须添加一个比较数字的函数,如以下代码:- <script type="text/javascript"> function sortNumber(a,b) { return a - b; } var n = ["10", "5", "40", "25", "100", "1"]; document.write(n.sort(sortNumber)); &

最近,当我使用JavaScript“sort()”函数时,我发现其中一个函数不能正确地对数字进行排序。要对数字进行排序,必须添加一个比较数字的函数,如以下代码:-

<script type="text/javascript">
function sortNumber(a,b)
{
    return a - b;
}

var n = ["10", "5", "40", "25", "100", "1"];
document.write(n.sort(sortNumber));
</script>
现在我不明白的是为什么会发生这种情况&有人能详细告诉我在这个“sort()”函数中使用了什么类型的算法吗?这是因为对于任何其他语言,我都没有发现函数没有正确排序数字的问题


非常感谢您的帮助。

如果您要对以下列表进行排序,它只包含字符串:

var n = ["10", "5", "40", "25", "100", "1"];
因此,我认为任何语言都会将它们作为字符串进行比较,从而得出以下排序顺序:

var n = ["1", "10", "100", "25", "40", "5"];
这就要求代码使用自定义排序(正如您所做的那样)将字符串转换回整数以进行排序

编辑

正如Pointy提到的,默认情况下,元素按字母顺序排序,包括数字:

默认情况下,sort()方法按字母顺序和升序对元素进行排序。但是,数字将无法正确排序(40排在5之前)。要对数字进行排序,必须添加一个比较数字的函数


简直太神奇了。。。因此,即使是整数数组也需要自定义排序。

如果n定义为:

var n = [10, 5, 40, 25, 100, 1]; 

问题在于使用字符串来表示数字,不幸的是排序函数默认使用字符串。字符串按字母顺序排序。代码中的比较函数只是强制将字符串作为数字进行计算


我认为这是非常糟糕的API设计,排序函数默认为将元素作为字符串处理,但可能需要JavaScript的松散类型系统。

< JavaScript的排序按默认字典排序,按字母顺序排序。因此,据我所知,每个元素都被视为一个字符串。内部排序算法很可能是快速排序或合并排序。为了能够使用快速排序,您需要能够将元素彼此关联起来,a比b大吗?在字符串情况下,已经实现了这种排序

由于您可能希望对自定义数据类型等进行排序,因此可以提供一个函数来定义如何对两个元素进行排序

从你的例子中,你的函数决定了两个数字a和b的顺序。Javascript sort然后使用函数告诉sort如何对元素排序


原来Mozilla使用mergesort,请看:

函数
sort
将以的形式对数组进行排序,即使它由整数组成;这就是数组通过调用
sort
而不带参数进行排序的原因

sortOrder
是一个比较函数,用于定义数组的新排序顺序;此函数将返回

  • 0
    ,如果
    a
    b
    的值相同
  • >0
    ,如果
    a
    的值大于
    b
  • a值
    <0
    ,如果
    a
    的值小于
    b

在JavaScript中,
“1”-“2”
将返回
-1
,这是一个数字,不再是字符串;通过在由字符串包裹的数字组成的数组上使用比较函数
sortOrder
,您可以按数字排序顺序对数组排序,从而产生
1,5,10,25,40100
,而不是
1,10100,25,40,5
,您可以将排序委托给自己的排序函数:

function sortnum(a,b) {
 return parseInt(a,10)-parseInt(b,10);
}
var n = ["10", "5", "40", "25", "100", "1"];
alert(n.sort(sortnum)); //=>["1", "5", "10", "25", "40", "100"]

为了回答您关于排序功能如何工作的问题,我将详细解释它。正如在这里的大多数答案中所说的,仅对数组调用
sort()
,将使用字符串对数组进行排序。也可以将整数转换为字符串。哎哟

如果您认为您的项目是字符而不是数字,那么按这种方式排序是有道理的。了解这一点的一个好方法是为数字指定字母

//0 = a
//1 = b
//2 = c
//4 = e
//5 = f
//These two arrays are treated the same because they're composed of strings.
var nums  = ["10", "5", "40", "25", "100", "1"];
var chars = ["ba", "f", "ea", "cf", "baa", "b"];

//Here we can see that sort() correctly sorted these strings. Looking at the
//alphabetical characters we see that they are in the correct order. Looking
//at our numbers in the same light, it makes sense that they are sorted
//this way as well. After all, we did pass them as strings to our array.
chars.sort(); //["b", "ba", "baa", "cf", "ea", "f"]
nums.sort();  //["1", "10", "100", "25", "40", "5"]

//The bad part of sort() comes in when our array is actually made up of numbers.
var nums = [10, 5, 40, 25, 100, 1];
nums.sort(); //[1, 10, 100, 25, 40, 5]

//As a result of the default sorting function converting numbers to strings 
//before sorting, we get an unwanted result. We can fix this by passing in our 
//own function as a parameter to sort().
通过将自己的函数作为参数传递给
sort()
函数,可以控制如何对数组进行排序。这很好,但是除非您知道
sort()
函数是如何工作的,否则它真的不会对您有任何好处

sort()
将多次调用函数以重新排列数组。根据函数返回的内容,告诉
sort()
如何处理数组中的项。如果返回负数或0,则不会重新排列。如果返回一个正数,则两个项目将切换到位
sort()
跟踪它已经测试过的数字,这样它就不会在切换项目后再次测试数字。如果
sort()
重新排列项目,它将向后移动一个位置,并查看之前是否测试过这两个项目。如果没有,它将测试它们。如果有,它将继续运行,而不在它们上运行您的函数

排序编号 让我们举一个简单的例子,我将向您介绍:

var arr = [50, 90, 1, 10, 2];

arr = arr.sort(function(current, next){
    //My comments get generated from here
    return current - next;
});

//1 : current = 50, next = 90
//  : current - next (50 - 90 = -40)
//  : Negative number means no re-arranging
//  : Array now looks like [50, 90, 1, 10, 2]
//
//2 : current = 90, next = 1
//  : current - next (90 - 1 = 89)
//  : Positive number means sort() will switch these positions in the array
//  : Array now looks like [50, 1, 90, 10, 2]
//
//If sort() didn't backtrack, the next check would be 90 and 10, switch those 
//positions, check 90 and 2, and switch again. Making the final array
//[50, 1, 10, 2, 90], not sorted. But lucky for us, sort() does backtrack.
//
//3 : current = 50, next = 1
//  : current - next (50 - 1 = 49)
//  : Positive number means sort() will switch these positions in the array
//  : Array now looks like [1, 50, 90, 10, 2]
//
//If sort() wasn't smart, it would now check 50 and 90 again. What a waste! 
//But lucky for us again, sort() is smart and knows it already made this 
//check and will continue on.
//
//4 : current = 90, next = 10
//  : current - next (90 - 10 = 80)
//  : Positive number means sort() will switch these positions in the array
//  : Array now looks like [1, 50, 10, 90, 2]
//
//sort() backtracks one position and sees that it has not checked 50 and 10
//
//5 : current = 50, next = 10
//  : current - next (50 - 10 = 40)
//  : Positive number means sort() will switch these positions in the array
//  : Array now looks like [1, 10, 50, 90, 2]
//
//sort() backtracks one position and sees that it has not checked 1 and 10
//
//6 : current = 1, next = 10
//  : current - next (1 - 10 = -9)
//  : Negative number means no re-arranging
//  : Array now looks like [1, 10, 50, 90, 2]
//
//sort() remembers that it already checked 10 and 50 so it skips ahead
//sort() remembers that it already checked 50 and 90 so it skips ahead
//
//7 : current = 90, next = 2
//  : current - next (90 - 2 = 88)
//  : Positive number means sort() will switch these positions in the array
//  : Array now looks like [1, 10, 50, 2, 90]
//
//sort() backtracks one position and sees that it has not checked 50 and 2
//
//8 : current = 50, next = 2
//  : current - next (50 - 2 = 48)
//  : Positive number means sort() will switch these positions in the array
//  : Array now looks like [1, 10, 2, 50, 90]
//
//sort() backtracks one position and sees that it has not checked 10 and 2
//
//9 : current = 10, next = 2
//  : current - next (10 - 2 = 8)
//  : Positive number means sort() will switch these positions in the array
//  : Array now looks like [1, 2, 10, 50, 90]
//
//sort() backtracks one position and sees that it has not checked 1 and 2
//
//10: current = 1, next = 2
//  : current - next (1 - 2 = -1)
//  : Negative number means no re-arranging
//  : Array now looks like [1, 2, 10, 50, 90]
//
//sort() remembers that it already checked 2 and 10 so it skips ahead
//sort() remembers that it already checked 10 and 50 so it skips ahead
//sort() remembers that it already checked 50 and 90 so it skips ahead
//sort() has no more items to check so it returns the final array
//which is [1, 2, 10, 50, 90]
如果希望数组按降序排列
[90,50,10,2,1]
,只需将return语句从
return current-next
返回下一个-当前像这样:

var arr = [50, 90, 1, 10, 2];

arr = arr.sort(function(current, next){
    //My comments get generated from here
    return next - current;
});

//1 : current = 50, next = 90
//  : next - current (90 - 50 = 40)
//  : Positive number means sort() will switch these positions in the array
//  : Array now looks like [90, 50, 1, 10, 2]
//
//2 : current = 50, next = 1
//  : next - current (1 - 50 = -49)
//  : Negative number means no re-arranging
//  : Array now looks like [90, 50, 1, 10, 2]
//
//etc.
当您使用自己的函数对数字进行排序时,数组是由“字符串数字”
“5”
组成还是仅由数字组成并不重要。因为当JavaScript进行数学运算时,它将“字符串数字”视为数字。i、 e.
“5”-“3”=2

排序字符串 对字符串排序时,可以使用
var arr = [50, 90, 1, 10, 2];

arr = arr.sort(function(current, next){
    //My comments get generated from here
    return next - current;
});

//1 : current = 50, next = 90
//  : next - current (90 - 50 = 40)
//  : Positive number means sort() will switch these positions in the array
//  : Array now looks like [90, 50, 1, 10, 2]
//
//2 : current = 50, next = 1
//  : next - current (1 - 50 = -49)
//  : Negative number means no re-arranging
//  : Array now looks like [90, 50, 1, 10, 2]
//
//etc.
var arr = ['banana', 'orange', 'apple', 'grape'];

arr = arr.sort(function(current, next){
    return current > next;
});
var arr = ['banana', 'orange', 'apple', 'grape'];

arr = arr.sort(function(current, next){
    return current > next? 1: -1;
});
var arr = [
    {id: 2, name: 'Paul'},
    {id: 1, name: 'Pete'}
];

//sort numerically
arr = arr.sort(function(current, next){
    return current.id - next.id;
});
//Array now looks like [{id: 1, name: 'Pete'}, {id: 2, name: 'Paul'}]

//sort alphabetically
arr = arr.sort(function(current, next){
    return current.name > next.name? 1: -1;
});
//Array now looks like [{id: 2, name: 'Paul'}, {id: 1, name: 'Pete'}]