【排序大乱炖】JavaScript实现各种排序

冒泡排序

//冒泡排序
function BubbleSort(arr){
	var len = arr.length,temp;
	for(var i = len; i > 0; i--){
		for(var j = 0; j < i - 1; j++ ){
			if(arr[j] > arr[j+1]){
				temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
			}
		}
	}
	return arr;
}

快速排序

function quickSort(array,start,end){
	if(start<end){//进行递归的条件,当start不再小于end也就说明排序完成了,不需要再进行递归了
		var index = array[start];
		var low = start,high = end;
		while(low<high){
			while(low<high&&index<=array[high]){
				high--;
			}
			//当array[high]小于基数,则将array[high]移至前面
			array[low] = array[high];
			while(low<high&&index>=arr[low]){
				low++;
			}
			array[high] = array[low];
		}
		//
		array[low] = index;
		//一次排序之后,已经以基数为中心将数组分成两个部分
		//再进行递归排序
		quickSort(array,start,low);
		quickSort(array,low+1,end);
	}
	return array;
}

选择排序

//选择排序
function ChooseSort(arr){
	var temp,Min;
	var len = arr.length;
	for(var i =0 ;i < len-1; i++){//length-1防止下一个循环j出现数组越界问题
		Min = i;
		for(var j = i+1; j < len; j++){
			if(arr[Min] > arr[j]){
				Min = j;//记录遇到的最小数的下标
			}
		}
		if(Min != i){
			temp = arr[i];
			arr[i] = arr[Min];
			arr[Min] = temp;
		}
		
	}
	return arr;
}

插入排序

// 插入排序
function insertSort(array){
	var temp,j;
	for(var i = 1; i < array.length; i++){
		//当后一个数比前一个数小的时候
		if(array[i] < array[i-1]){
			temp = array[i];
			//遍历i之前的数,并与a[i](temp)进行比较,比temp大的往后移,直到遇到比temp小的,将temp放到该位置
			for(j = i-1; j >= 0&&array[j] > temp; j--){
				array[j+1] = array[j];
		}
		array[j+1] = temp;
	}
}
return array;
}

希尔排序

//希尔排序
function shellSort(array){
	var temp;
	//遍历所有的步长
	//这里注意除以2,因为JavaScript里可能会出现精度丢失或者变成浮点数而陷入死循环或者运行崩溃,
	//不能向上取整因为会使1/2=1陷入死循环,所以向下取整才能取到0
	for(var i = Math.floor(array.length/2);i>0;i=Math.floor(i/2)){
		//遍历所有的元素
		for(var j = i; j < array.length; j++){
			//对组中的元素进行比较
			for(var k = j - i; k>=0; k-=i){
				if(array[k] > array[k+i]){
					temp = array[k];
					array[k] = array[k+i];
					array[k+i] = temp;
				}
			}
		}
	}
	return array;
}

归并排序

//归并排序

var merges = [3,6,9,1,4,5,7,8];
function MergeSort(array,start,end){
	let middle = Math.floor((start+end)/2);
	if(start<end){
		MergeSort(array,start,middle);
		MergeSort(array,middle+1,end);
		merge(array,start,middle,end);
	}
	return array;
}
function merge(array,start,middle,end){
	let index = 0;
	//临时数组,存放归并后的序列
	let temp = [];

	let j = middle+1,i = start;
	while(i<=middle&&j<=end){
		if(array[i] < array[j]){
			temp[index] = array[i];
			i++;
		}else{
			temp[index] = array[j];
			j++;
		}
		index++;
	}
	//处理剩下未归并的序列
	while(i<=middle){
		temp[index] = array[i];
		index++;
	}
	while(j<=end){
		temp[index] = array[j];
		index++;
	}
	//将临时数组中的数据放回原数组
	for(let k = 0; k < temp.length; k++){
		array[k+start] = temp[k];
	}
}

基数排序

//基数排序
function radixSort(array){
	//首先遍历数组,找出最大的数
	let max = 0;
	for(let i = 0; i < array.length; i++){
		let temp = 0;
		if(array[i] > max){
			max = array[i];
		}
	}
	//求数组中最大数的长度
	max = max + "";
	//创建一个二维数组来暂时存放以基数分类的元素
	var temp = [];
	for(let i = 0; i < 10; i++){
		temp[i] = [];
		for(let j = 0; j < array.length; j++){
			temp[i][j] = 0;
		}
	}
	// for(let value of temp){
	// 	console.log(value);
	// }
	//存放每个对应的二维数组里存了几个元素
	var counts = [];
	for(let i = 0; i < 10; i++){
		counts[i] = 0;
	}
	
	//首先遍历数组,从个位开始
	//console.log(max.length);
	for(let i = 0,n = 1; i < max.length; i++,n*=10){
		for(let j = 0; j < array.length; j++){
			let te = (Math.floor(array[j]/n))%10;//
			//console.log(te);
			temp[te][counts[te]] = array[j];
			counts[te]++;
		}
	// if(i==1){
	// 	for(let value of temp){
	// 		console.log(value);
	// 	}
	// }
		var index = 0;
		for(let k = 0; k < counts.length; k++){
			if(counts[k] != 0){
				for(let m = 0; m < counts[k]; m++){
				array[index] = temp[k][m];
				index++;
				temp[k][m] = 0;
				}
			//因为还要进行循环,所以要将计数进行清零
			counts[k] = 0;
			}
		//console.log(array);
		}
		console.log(array);
	}
}

堆排序

function HeapSort(array){
	//堆排序符合完全二叉树的规则,完全二叉树的最后一个非叶子节点为n/2-1
	//开始位置是最后一个非叶子节点,也就是最后一个叶子节点的父节点
	let start = Math.floor(array.length/2-1);
	//let start = array.length/2-1;
	//console.log(start);
	//调整为大顶堆
	for(let i = start;i>=0;i--){
		MaxHeap(array,array.length,i);
	}
	//console.log(array);
	//排序
	for(let i = array.length-1;i>0;i--){
		//依次将大顶堆第一个元素换到后面
		let temps = array[0];
		array[0] = array[i];
		array[i] = temps;
		//重排大顶堆,保证第一个节点是最大的
		MaxHeap(array,i,0);
	}
	//打印排序后的数组
	console.log(array);
	//需要一个将数组元素转成大顶堆的方法
	function MaxHeap(array,size,index){
		let temp;
		//左子节点
		let leftNode = 2*index+1;
		//右子节点
		let rightNode = 2*index+2;
		let max = index;
		//对比两个子节点,找出最大的节点
		if(leftNode<size&&array[leftNode]>array[max]){
			max = leftNode;
		}
		if(rightNode<size&&array[rightNode]>array[max]){
			max = rightNode;
		}
		//交换位置
		if(index != max){
			temp = array[index];
			array[index] = array[max];
			array[max] = temp;
			//交换位置之后,可能会破坏之前的堆,所以,需要重排
			MaxHeap(array,size,max);
		}
		
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值