1.快速排序
算法步骤:
- 在数组中找到基准点(flag),其他数与之比较。
- 建立两个数组,小于基准点的数存储在左边数组,大于基准点的数存储在右边数组。
- 拼接数组,然后左边数组与右边数组继续执行1、2两个步骤,直到最后完成数组排序。(该步骤可以看出算法存在迭代性质)
function quicksort(arr){
if(arr.length<=1)
{
return arr ; // 如果数组长度小于或等于1,则直接返回数组(也是跳出循环的条件)
}
var num = Math.floor(arr.length/2); // 找到数组中间的索引,如果是浮点数,则向下取整
var center = arr.splice(num,1); // 找到数组中间索引的值
var left = [];
var right = [];
for(var i=0;i<arr.length;i++){
if(arr[i]<center)
{
left.push(arr[i]); // 基准点左边的数放到左边数组
}
else{
right.push(arr[i]);// 基准点右边的数放到右边数组
}
}
// 利用concat拼接数组(注意不要遗漏中间值),并调用quickSort方法,利用递归的方法
return quicksort(left).concat([center],quicksort(right));
}
consloe.log(quicksort([2,4654,798,313,453,15,16,43]));//对一堆数进行排序
将一个数组不断分成较大较小的两部分,直至不能分时,数组就排序完毕,这是快速排序的核心思想。
2.二路归并排序
- 先将数组C划分为两个数组A和B(即把数组C从中间分开)
- 再分别对数组A、B重复步骤1的操作,逐步划分,直到不能再划分为止(每个子数组只剩下一个元素),这样,划分的过程就结束了。
- 然后从下层往上层不断合并数组,每一层合并相邻的两个子数组,合并的过程是每次从待合并的两个子数组中选取一个最小的元素,然后把这个元素放到合并后的数组中,不断重复直到把两个子数组的元素都放到合并后的数组为止。
依次类推,直到合并到最上层结束,这时数据的排序已经完成了。
function merge(left, right) {
var result = [];
while((left.length > 0) && (right.length > 0))
{
if(left[0] < right[0]) //将数组元素比较并进行排序
{
result.push(left.shift());
}
else
{
result.push(right.shift());
}
}
//当左右数组长度不等.将比较完后剩下的数组项链接起来即可
return result.concat(left).concat(right);
}
function mergeSort(arr){
if(arr.length==1)
{
return arr;
}
var mid=Math.floor(arr.length/2);//将数组分成左右两部分,向下取整
var left_arr=arr.slice(0,mid);
var right_arr=arr.slice(mid);
return merge(mergeSort(left_arr),mergeSort(right_arr));
}
var arr=[12,20,30,21,15,33,26,19,40,25];//对数组元素进行排序
console.log(mergeSort(arr));
算法分析
每一趟归并的时间复杂度为O(n),共需要进行⌈log2n⌉趟。对应的算法的时间复杂度为O(nlog2n)。归并排序的空间复杂度O(n)。另外,归并排序中归并的算法并不会将相同关键字的元素改变相对次序,所以归并排序是稳定的。