JavaScript排序

本文详细介绍了六种常用的排序算法,包括希尔排序、计数排序、基数排序、桶排序、归并排序和堆排序。通过实例展示了每种算法的具体实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.希尔排序:建立在直接插入排序基础上。

比如数组[ 13, 14, 94,33, 82, 25, 59, 94, 65, 23, 45, 27, 73, 25, 39, 10],设置步长5

13, 14, 94, 33, 82, 

25, 59, 94, 65, 23, 

45, 27, 73, 25, 39, 

10

对每进行插入排序:5列同时进行插入排序,不是一列插入排序完成后,再对列一列进行插入排序

25和13比较,59和 14比较,94和94比较,65和33比较 23和82比较得到结果

13, 14, 94, 33, 23, 

25, 59, 94, 65, 82, 

45, 27, 73, 25, 39, 

10

到45的时候,相当于13,25,45进行插入排序,

到27的时候,对14,59,27进行插入排序,依次类推。

完成排序后,再将步长变成2,进行上述操作,直至步长变成1。

function shellSort(list) {
    var gap = list.length / 2;
 
    while (1 <= gap) {
        // 把距离为 gap 的元素编为一个组,扫描所有组
        for (var i = gap; i < list.length; i++) {
            var j = 0;
            var temp = list[i];
 
            // 对距离为 gap 的元素组进行排序
            for (j = i - gap; j >= 0 && temp < list[j]; j = j - gap) {
                list[j + gap] = list[j];
            }
            list[j + gap] = temp;
        }
        gap = gap / 2; // 减小增量
    }
}
var arr = [ 13, 14, 94,33, 82, 25, 59, 94, 65, 23, 45, 27, 73, 25, 39, 10];
shellSort(arr);
console.log(arr);//[ 10, 13, 14, 23, 25, 25, 27, 33, 39, 45, 59, 65, 73, 82, 94, 94 ]

2.计数排序:计算数字出现的次数,该方法数字的范围就是数组的长度

对数值范围0-9的数进行排序

[6, 2, 8, 5, 2, 5, 6, 7, 9, 8, 3, 1, 5, 6, 2,5,9,7,5,1]

将数字出现的次数存放到该数字对应下标的数组中,例如数字2出现了3次,arr[2]=3


'use stirct';
function countSort(arr){
	var countArr = new Array(20);
	countArr.fill(0);
	var result = [];
	for(var i = 0; i<arr.length;i++){
		countArr[arr[i]]++
	}
	for(var j = 0;j<countArr.length;j++){
		while(countArr[j]--){
			result.push(j);
		}
	}
	return result;
}
var arr = [6, 2, 8, 5, 2, 5, 6, 7, 9, 8, 3, 1, 5, 6, 2,5,9,7,5,1];
console.log(countSort(arr));
//[ 1, 1, 2, 2, 2, 3, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9 ]

3.基数排序:

首先根据个位数的数值,在遍历数据时将它们各自分配到编号0至9的桶(个位数值与桶号一一对应)中


合并成一个数组[ 60, 81, 72, 123, 23, 24, 555, 36, 89, 99 ]

根据十位数的数值,在遍历数据时将它们各自分配到编号0至9的桶(个位数值与桶号一一对应)中


合并成一个数组[ 123, 23, 24, 36, 555, 60, 72, 81, 89, 99 ]

根据百位数的数值,在遍历数据时将它们各自分配到编号0至9的桶(个位数值与桶号一一对应)中


得到数组[ 23, 24, 36, 60, 72, 81, 89, 99, 123, 555 ],完成排序。

'use stirct';
function getDigit(x,d){   
     var a = [1, 10, 100]; 
     return Math.floor(x/a[d]) % 10;  
}  
var d = 0;
function radixSort(arrnum,d){
	if(d>2){
		return arrnum;
	}
	//创建容器
	var arr2 = new Array(10).fill(0);//数组内容是空时,执行map是无效的
	arr2 = arr2.map(function(){
		return [];
	})
	var arr1 = []; 
	//往容器中放数据
	arrnum.forEach(function(x){
		arr2[getDigit(x,d)].push(x);
	})
	//将二维数组变成一维数组
	arr2.forEach(function(arr){
		arr1 = arr1.concat(arr)
	});
	d++;
	return radixSort(arr1,d);
}
var arr = [89,60,123,23,555,81,72,24,36,99];
var a = radixSort(arr,d)
console.log(a);

桶排序:

将数字放入对应的桶中,

0号桶放 0-9

1号桶放 10-19,以此类推,

将各个桶中的数字排序,将所有桶按编号顺序合并

'use stirct';  
function bucketSort(arrnum){
	//创建容器
	var arr2 = new Array(10).fill(0);//数组内容是空时,执行map是无效的
	arr2 = arr2.map(function(){
		return [];
	})
	var arr1 = []; 
	//往容器中放数据
	arrnum.forEach(function(x){
		arr2[Math.floor(x/10)].push(x);
	});
	//一维数组排序
	arr2.forEach(function(arr){
		arr.sort(function(a,b){
			return a-b;
		});
	})
	//将二维数组变成一维数组
	arr2.forEach(function(arr){
		arr1 = arr1.concat(arr)
	});
	return arr1;
}
var arr = [89,60,32,12,55,81,72,24,36,99];
var a = bucketSort(arr)
console.log(a);

归并排序:将待排序的数列分成若干个长度为1的子数列,然后将这些数列两两合并;得到若干个长度为2的有序数列,再将这些数列两两合并,知道合并成一个数列。

function merge(arr, start, mid, end)
{   
	  var tmp = [];
    var i = start;            // 第1个有序区的索引
    var j = mid +1  ;        // 第2个有序区的索引
    var k = 0;                // 临时区域的索引

    while(i <= mid && j <= end)
    {
        if (arr[i] <= arr[j])
            tmp[k++] = arr[i++];
        else
            tmp[k++] = arr[j++];
    }

    while(i <= mid)
        tmp[k++] = arr[i++];

    while(j <= end)
        tmp[k++] = arr[j++];

    // 将排序后的元素,全部都整合到数组a中。
    for (i = 0; i < k; i++)
        arr[start + i] = tmp[i];
}
function mergeSort(arr,first,last)
       {
           if (first < last)
           {
               var mid = Math.floor((first + last) / 2) ;
               mergeSort(arr, first, mid);
               mergeSort(arr, mid+1, last);
               merge(arr, first, mid, last);
           }
       }

var arr = [25,89,56,67,29,55,33,68,15,82];
mergeSort(arr,0,9);
console.log(arr);//[ 15, 25, 29, 33, 55, 56, 67, 68, 82, 89 ]

堆排序:利用的是完全二叉树

function maxheapDown(a,n){
	  var c,l,tmp;
    for (i =Math.floor(n / 2 - 1); i >= 0; i--){
	     c = i;            // 当前(current)节点的位置
	     l = 2*c + 1;        // 左(left)孩子的位置
	     tmp = a[c];            // 当前(current)节点的大小
	    // "l"是左孩子,"l+1"是右孩子
	    if (a[l] < a[l+1])
	        l++;        // 左右两孩子中选择较大者,即m_heap[l+1]
	    if (tmp < a[l]){
	        a[c] = a[l];
	        a[l]= tmp;
	    }
    }
}
function swap(arr,i){
	var temp = arr[0];
	arr[0]=arr[i];
	arr[i]=temp;
}
function heapSort(arr)
  {
      var i;
      var n =arr.length
      for (i = n - 1; i > 0; i--)
      {
          maxheapDown(arr,i);
          // 交换a[0]和a[i]。交换后,a[i]是a[0...i]中最大的。
         swap(arr,i);
      }
 }
var arr = [25,89,56,67,29,55,33,68,15,82,11];
heapSort(arr)
console.log(arr);//[ 11, 15, 25, 29, 33, 55, 67, 56, 68, 82, 89 ]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值