JavaScript实现基本排序和二分查找

 

注:图转自:https://www.cnblogs.com/onepixel/articles/7674659.html

 

稳定排序是指序列中相同的两个数在排序后 先后位置不变。

var arr=[2,34,5,3,56,67,46];

冒泡排序

冒泡排序是从前往后相邻的两个数之间进行比较,大的排在后面,排完一轮后,最大的数排在后面,然后对

未排好的继续冒泡,每一次能找到未排序中最大的数,循环这个过程即可。

冒泡排序比较相邻的两个元素,如果相同,则不用交换,故冒泡排序是稳定的排序。

var arr=[2,34,5,3,56,67,46];

function bubble_sort(){
	for(var i=0;i<arr.length;i++){
	   for(var j=1;j<arr.length-i;j++){
		if(arr[j-1]>arr[j]){
		   temp=arr[j-1];
		   arr[j-1]=arr[j];
		   arr[j]=temp;
		}
	   }
	}
	console.log(arr);
}
bubble_sort();

 

选择排序

//选择排序:以第一个数为参照,将右边的数与其比较,如果比它小,则交换,排完一趟后第一个数是最小的;
// 第二趟以第二个数为参照,将右边的数与其比较,如果比它小,则交换,排完第二趟后第二个数是最第二小的;以此类推
function select(arr){
	for(let i=0;i<arr.length-1;i++){
	    for(let j=i+1;j<arr.length;j++){
	    if(arr[j]<arr[i]){
	       let temp=arr[i];
	       arr[i]=arr[j];
	       arr[j]=temp;
        }
    }
}
    return arr;
}
var arr = [1, 45, 37, 5, 48, 15, 37, 26, 29, 2, 46, 4, 17, 50, 52]; 
console.log(select(arr)); 

插入排序  

插入排序会将左边有序的数从右往左和它右边的第一个数比,所以排序后顺序不会改变,故插入排序是稳定排序。     

//先把第一个数看成序列的子序列,将第二个数与其比较,如果比它小,则排在前面,排完一轮后,有序的子序列有两个数;
//将有序的子序列中的每一个数与剩余序列的第一个数(b)比较,如果子序列中的某一个数比b大,则将b插入到其前面,

//循环下去,使得有序的子序列越来越长,直到排序完成

function insert(arr){
	for(let i=1;i<arr.length;i++){
	    let j=i-1;
	    let temp=arr[i]
	    while(j>=0&&arr[j]>temp){
	       arr[j+1]=arr[j];
	       j--;
        }
    arr[j+1]=temp;
}
    return arr;
}
var arr = [1, 45, 37, 5, 48, 15, 37, 26, 29, 2, 46, 4, 17, 50, 52]; 
console.log(insert(arr)); 

 

快速排序

//快速排序是选定参照数(以第一个数为例),设置i=0,j=arr.length-1,先从右往左寻找出第一个比当前数小的,
//然后交换顺序,此时j不断减小;接着从左往右寻找第一个比当前数大的,进行交换,如果i==j,第一次遍历结束。

//然后把参照数左右两边的数以同样的方式进行排序,可用递归的方法。

//第一种方法(摘自阮一峰的排序),时间和空间复杂度在基数较大时较高
function quickSort(arr){
            //如果数组<=1,则直接返回
            if(arr.length<=1){return arr;}
            var pivotIndex=Math.floor(arr.length/2);
            //找基准,并把基准从原数组删除
            var pivot=arr.splice(pivotIndex,1)[0];
            //定义左右数组
            var left=[];
            var right=[];

            //比基准小的放在left,比基准大的放在right
            for(var i=0;i<arr.length;i++){
                if(arr[i]<=pivot){
                    left.push(arr[i]);
                }
                else{
                    right.push(arr[i]);
                }
            }
            //递归
            return quickSort(left).concat([pivot],quickSort(right));
        }
quickSort([25,63,82,21,122,26])  

//第二种方法

function quickSort2(arr, begin, end) {
            if (begin >= end) {
                return;
            }
            //选组长
            var leader = arr[begin];
            var left = begin;
            var right = end;

            while(left < right) {
                //首先右边和leader比,因为leader的位置空出来了
                while (left < right) {
                    if (arr[right] < leader) {
                        arr[left] = arr[right];
                        left += 1;
                        break;
                    } else {
                        right -= 1;
                    }
                }
                while (left < right) {
                    if (arr[left] > leader) {
                        arr[right] = arr[left];
                        right -= 1;
                        break;
                    } else {
                        left += 1;
                    }
                }
            }
            arr[left] = leader;
            quickSort2(arr, begin, left - 1);
            quickSort2(arr, left + 1, end);
        }
let arr=[12,22,13,24,21,45,21];
quickSort2(arr, 0, 6);
arr;  

//第三种比第二种精简

function quickSort(arr,l,r){
	if(l>=r)
			return;
		let i=l;
let j=r+1;
let val=arr[l];
while(true){
	while (i<j&&arr[--j]>=val){};
	arr[i]=arr[j];
	while (i<j&&arr[++i]<=val){};
	arr[j]=arr[i];
if(i>=j){
	arr[j]=val;
	break;
}
}
quickSort(arr,l,j-1);
quickSort(arr,j+1,r);
}
var arr23=[12,32,8,10,99,23,14,98,32,33,11,10,32,45,34];
quickSort(arr23,0,arr23.length-1);
arr23;

堆排序

堆排序的过程如下:

堆排序有大根堆和小根堆,大根堆的每个父节点都不小于其左右两个子节点

大根堆:从倒数第二层开始,找出具有叶子节点的节点,将其与自己的子节点比较,将其与较大的叶子节点进行交换,arr[i]的两个子节点
为arr[2*i+1]和arr[2*i+2],从下往上直到i=0,此时arr[0]的值是最大的,将其与数组的最后一个位置进行替换,替换后可能无法构成
大根堆,需要照同样的方法进行,直到最后只有根节点,即最小的数。

function swap(arr,i,j){
	let temp=arr[i];
	arr[i]=arr[j];
	arr[j]=temp;
}
function shiftDown(arr,i,length){
	let temp=arr[i];
	for(let j=2*i+1;j<length;j=2*j+1){
		if(j+1<length&&arr[j]<arr[j+1]){
			j++;
		}
		if(temp<arr[j]){
			swap(arr,i,j);
			i=j;
		}else{
			break;
		}
	}
};
function heapSort(arr){
	for(let i=Math.floor(arr.length/2-1);i>=0;i--){
		shiftDown(arr,i,arr.length);
	}
	for(let i=arr.length-1;i>0;i--){
		swap(arr,0,i);
		shiftDown(arr,0,i);
	}
};
var arr=[12,3,45,43,3,54,34,6,7,2];
heapSort(arr);
console.log(arr);

归并排序:

//归并的思想是分割思想
function merge(left,right){
	console.log(left,right);
	var res=[];
	while(left.length>0&&right.length>0){ //其中一项为0,直接排序即可,毕竟已经是排好序的了
		if(left[0]<right[0]){
			res.push(left.shift());
		}else{
			res.push(right.shift())
		}
	}
	return res.concat(left,right);
};
function merge_sort(items){
	if(items.length===1){
		return items;
	}
	var mid=Math.floor(items.length/2);
	var left=items.slice(0,mid);
	var right=items.slice(mid);
	return merge(merge_sort(left),merge_sort(right)); //递归到得出一项一项的,再进行merge
};
merge_sort([1,3,53,23,5,26,4])

希尔排序

确定比较间隔

function shell_sort(arr){
	let length=arr.length;
	let gap=1;
	while(gap<length/3){
		gap=gap*3+1;
	}
	while(gap>=1){
		for(var i=gap;i<length;i++){
			for(var j=i;j>=gap&&arr[j]<arr[j-gap];j-=gap){
				swap(arr,j,j-gap);
			}
		}
		gap=(gap-1)/3;
	}
	console.log(arr);
}
function swap(arr,i,j){
	let temp=arr[i];
	arr[i]=arr[j];
	arr[j]=temp;
};
shell_sort([12,3,43,54,5,18])

二分查找:

function binary_search(arr,key){
	var low=0;
	var high=arr.length-1;
	while(low<=high){
		var mid=parseInt((high+low)/2);
		if(key===arr[mid]){
			return mid;
		}else if(key>arr[mid]){
			low=mid+1;
		}else if(key<arr[mid]){
			high=mid-1;
		}else{
			return -1;
		}
	}
};

递归方法:

function binary_search(arr,low,high,key){
	var mid=parseInt((high+low)/2);
	if(key===arr[mid]){
		console.log(mid);
		return mid;
	}else if(key>arr[mid]){
		low=mid+1;
		binary_search(arr,low,high,key);
	}else if(key<arr[mid]){
		high=mid-1;
		binary_search(arr,low,high,key);
	}else{
		return -1;
	}
};
var arr=[1,2,3,5,6,33];
binary_search(arr,0,arr.length-1,2)

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值