排序:
1.选择排序:
/**
* 交换数组两个下标的数据
* @param {*} arr
* @param {*} i1
* @param {*} i2
*/
function swap(arr,i1,i2){
var temp=arr[i1];
arr[i1]=arr[i2];
arr[i2]=temp;
}
function selectionSort(arr){
for(var i=0;i<arr.length-1;i++){
//数组长度为len,循环的次数为len-1
//第一次循环,也就是i=0这个循环次数指针,在下标0-len-1的范围内找到最小值,和下标为0的元素进行交换。
//第二次循环,也就是i=1这个循环次数指针,在下标1-len-1的范围内找到最小值,和下标为1的元素进行交换。
//第i+1次循环,也就是i=i这个循环次数指针,在下标i-len-1的范围内找到最小值,和下标为i的元素进行交换。
//1.在下标i-len-1的范围内找到最小值,将第一个数作为参考当作最小值,和其他的元素进行比较。
var min=arr[i];
var index=i;
//找到最小值,并找到对应的下标,得需要两个变量保存。
for(j=i+1;j<arr.length;j++){
if(arr[j]<min){
min=arr[j];
index=j;
}
}
//循环结束之后得到的index就是当前循环中最小值的下标
//2.最小数字和下标为i的元素进行交换
swap(arr,i,index);
}
}
var arr=[5,3,1,4,2];
selectionSort(arr);
console.log(arr);
2.冒泡排序:
function swap(arr,i1,i2){
var temp=arr[i1];
arr[i1]=arr[i2];
arr[i2]=temp;
}
function bubbleSort(arr){
//两层循环
for(var i=0;i<arr.length-1;i++){
//数组长度为len,循环的次数为len-1
//第0次,将0-len-1中的最大值放到len-1的位置
//第1次,将0-len-2中的最大值放到len-2的位置
//第i次,将0-len-1-i中的最大值放到len-1-i的位置
//在每次循环中,比较前一个数和后一个数的大小,如果前面的比后面的大,交换
//len-2-i是因为最后一个数不需要再和下一个元素比较了,因为下一个元素没有值
for(j=0;j<=arr.length-2-i;j++){
if(arr[j]>arr[j+1]){
swap(arr,j,j+1);
}
}
}
}
var arr=[5,3,1,4,2];
bubbleSort(arr);
console.log(arr);
3.快速排序:
function swap(arr,i1,i2){
var temp=arr[i1];
arr[i1]=arr[i2];
arr[i2]=temp;
}
function quickSort(arr){
/**
* 在start-end之间,对数组完成快排
* @param {*} start
* @param {*} end
*/
function _quickSort(start,end){
var low=start;
var high=end;
var key=arr[end];// 基准数
//特殊情况的一个排除
if(start<0||end>=arr.length||start>end)
{
//1. 起始位置大于等于了结束位置
//2. 结束位置大于了最大下标
//3. 起始位置小于了最小下标
// 无须排序
return;
}
while(low<high){
//1. low不断的向右移动,直到遇到比基准数大的
while((low<high)&&(arr[low]<=key)){
low++;
}
arr[high]=arr[low];//将low的值给high.
//2. high不断的向左移动,直到遇到比基准数小的
while((low<high)&&(arr[high]>=key)){
high--;
}
arr[low]=arr[high];
}
//整个循环结束时,low === high
arr[low]=key;
// //搞定左边的小数字
_quickSort(start,low-1);
搞定右边的大数字
_quickSort(low+1,end);
}
_quickSort(0,arr.length-1);
}
var arr=[1,1,1,1,2];
quickSort(arr);
console.log(arr);
查找:
二分查找:
如果一个序列是一个排序好的序列,则使用二分查找可以极大的缩短查找时间
// 具体的做法是:
// 查找该序列中间未知的数据
// 1) 相等,找到
// 2) 要找的数据较大,则对后续部分的数据做同样的步骤
// 3) 要找的数据较小,则对前面部分的数据做同样的步骤
function binarySearch(arr,value){
var minIndex=0;
var maxIndex=arr.length-1;
while(maxIndex>= minIndex){
count++;
var mid=Math.floor((minIndex+maxIndex)/2);//中间下标
if(arr[mid]===value){
return true;
}else if(arr[mid]>value){
maxIndex=mid-1;
}else{
minIndex=mid+1;
}
}
return false;
}
var arr=[1,2,5,6,7,8,9];
var count=0;
console.log(binarySearch(arr,6));
console.log(count);
插值查找 Interpolation Search
插值查找是对二分查找的进一步改进
如果序列不仅是一个排序好的序列,而且序列的步长大致相同,使用插值查找会更快的找到目标。
插值查找基于如下假设:下标之间的距离比和数据之间的距离比大致相同
于是有
(target - a) / (g - a) ≈ (mid - minIndex) / (maxIndex - minIndex)
从而有
mid ≈ (target - a) / (g - a) * (maxIndex - minIndex) + minIndex
代码待考证