算法与数据结构
常用算法的代码实现(JavaScript版)
二分查找
function Binary_search(list, item){
let low = list[0];
let high = list.length-1;
while(low<=high){
let mid = Math.floor((low+high)/2);
let guess = list[mid];
if(guess===item){
return mid;
}
if(guess>item){
high = mid - 1;
}else{
low = mid + 1;
}
}
return null;
}
const arrList =[1,2,3,4,5,6,7];
console.log( Binary_search(arrList, 5) ); //4
console.log( Binary_search(arrList, -1)); //null
- 首先声明一个最小变量的索引,且把第一个当成最小的元素,最后那个为最大的元素
- 只有当左边元素小于右边元素,循环
- 把中间的元素索引赋值为mid
- 比较guess和item值(你要查找的值)的大小,找到就返回
- 若是比你预想的要大,则mid右边的值全都不要,反之亦然
二分查找是一种在有序数组中查找某一特定元素的搜索算法
最坏时间复杂度 O(log n)
最优时间复杂度 O(1)
平均时间复杂度 O(log n)
选择排序
function findSmallest(array){
let smallest = array[0];
let smallest_index = 0;
for(var i = 1;i<array.length;i++){
if(smallest>array[i]){
smallest = array[i];
smallest_index = i;
}
}
return smallest_index;
}
function selectionSort(array){
let array.length = length;
let sortedArray = [];
for(var i=0; i<length; i++){
smallest = findSmallest(array);
sortedArray.push( array.splice(smallest_index,1)[0] );
}
return sortedArray;
}
console.log( selectionSort([5,3,2,6,2,10]) ); //[2,3,5,6,10]
- 首先第一步就是创建一个专门用于搜索最小值的函数,遍历一遍数组寻找最小值
- 第二步就是选择排序,创建一个新数组用于存放已经排序好的元素
- 把每次寻得的数组里的最小值压入已经排序的数值,栈底是最小的,最后返回已经排好序的数组
最坏时间复杂度 O(n²)
最优时间复杂度 O(n²)
平均时间复杂度 O(n²)
递归
调用栈的概念
function greet2(name){
console.log("how are you, "+name+"?");
}
function bye(){
console.log("bye!");
}
function greent(name){
console.log("Hello,"+name+"!");
greent2(name);
console.log("Time to say goodbye");
bye()
}
- 调用函数,计算机为该函数分配一块内存空间
- 然后函数存入变量name,并把name设置成MAGGIE存到内存中
- 当你调用函数是,计算机把所有设计到的所有变量都存储起来,打印
Hello,MAGGIE!
。随后调用greet2,同样也要分配内存
- 这时候计算机打印出来
how are you, MAGGIE?
,随后函数便从栈顶弹出 - 此时栈顶的函数就是greet,而后打印
Time to say goodbye
。紧接着又调用bye()
,同样压入栈顶 - 函数greet还没有完全执行完毕,只执行一部分,计算机内存会保存函数在该状态下的所有变量
- 调用另一个函数的时候,当前函数暂停并处于未完成状态中,最后打印
bye!
- 打印完毕就把函数
bye()
从栈顶移除
- 最后greet()函数也会从栈顶移除
递归函数
function fact(x){
if(x==1){
return 1;
}else{
return x*fact(x-1);
}
}
console.log(fact(5));
快速排序
function quickSort(array){
if(array<2){
return array;
}else{
let pivot = array[0];
let less = array.slice(1).filter(function(el){
return el <= pivot;
});
let greater = array.slice(1).filter(funcrion(el){
return el > pivot;
})
return quickSort(less).concat([pivot],quickSort(greater));
}
}
console.log(quickSort([10,5,2,3]));
- 快速排序的核心就是选择一个基准点,然后比较分成两拨数组
- 使用递归函数调用分开的数组,当数组元素少于2时就证明已经排序(结束的条件)
最坏时间复杂度 O(n²)
最优时间复杂度 O(n log n)
平均时间复杂度 O(n log n)
下面我们来看一下最环的时间复杂度:
- 当我们选择的基准点是第一个时,会出现这种情况
- 但是如果我们能选择好的基准点就会快很多
- 最坏情况下栈长为O(n)
- 最佳情况下是O(log n)
以上图片均来源于维基百科和《算法图解》插图