js数据结构与算法

一、javascript基础
1.javascript的数据类型有:数字、字符串、函数、对象、undefined、null和数组、日期、正则表达式。
2.变量作用域:本地变量和全局变量。在一个函数里,变量没有使用var 关键字,则是申明或者引用了全局变量。
3.转换为布尔值为假值的有
|undefined|
|-null-|
| +0,-0,NaN |
"" 空字符串
4.创建对象两种方式:构造函数和字面量方式创建
5.数组

  1. 一维数组

添加:结尾:push  ;开头:unshift

删除:结尾:pop  ;删除第一个元素:shift()
任意位置删除或添加元素splice
numbers.splice(5,3):删除从数组索引5开始的3个元素
numbers.splice(5,0,2,3,4):从索引5开始,删除0个元素,之后3个参数就是要添加到数组里的值

  1.  二维和多维数组  

用数组嵌套实现矩阵或多维数组

  1. 数组的核心方法
方法名描述
every对数组的每一项运行给定函数,如果该函数对每一项都返回true,则返回true
filter对数组的每一项运行给定函数,返回该函数会返回true的项组成的数组
forEach对数组的每一项运行给定函数,这个方法没有返回值
indexOf返回第一个与给定参数相等的数组元素的索引
map对数组的每一项运行给定函数,返回每次函数调用的结果组成的数组
slice传入索引值,将数组里对应索引范围内的元素作为新数组返回
splice可以对数组任意索引位置处进行增加和删除

如果需要迭代整个数组,可以用forEach 。

返回新数组的遍历方法

map  返回的数组里面包含了传入map方法的函数的运行结果(返回值)

filter 返回的新数由使函数返回true的元素组成

reduce 接收一个函数作为参数,这个函数有4个参数,previousValue、currentValue、index、array.返回一个将被叠加到累加器的值,reduce方法停止执行后会返回这个累加器。

二、栈:后进先出

实现栈,用数组来保存栈里的元素

function Stack(){
  var items=[];
  this.push=function(el){  //入栈
    items.push(el);
    }
  this.pop=function(el){    //出栈
    items.push(el);
    }
  this.peek=function(el){    //返回栈顶元素
    return items[items.length-1];
    }
  this.isEmpty=function(el){   //判断栈是否为空
    return items.length==0;
    }
   this.clear=function(){
       items=[];
   }
}

使用:

var stack=new Stack();
stack.push(5);
stack.push(8);
stack.pop();  //移除8
stack.peek();  //栈顶元素此时为5

三、队列:先进先出

function Queue(){
  var items=[];
  this.enqueue=function(el){  //向队列尾部添加元素
      items.push(el);
    }
  this.dequeue=function(){   //移除队列的第一项,并返回被移除的元素
      items.shift();
    }
  this.front=function(){  //返回队列最前面的项
     return items[0];
    }
  }

使用:

var queue=new Queue();
queue.enqueue("Jhon")
queue.enqueue("lisa")
queue.dequeue()   //剩余lisa

优先队列:元素的添加和移除是基于优先级的

function PriorityQueue(){
   var items=[];
   function QueueElement(Value,Priority){
      this.value=Value;
      this.proiority=Priority
   }
   this.enqueue=function(el,priority) { //给队列添加元素,必须传入两个参数,一个是元素的值,一个是优先级
   var queueElement=new QueueElement(el,priority)  //生成QueueElement对象实例
   if(this.isEmpty()){  //如果是空队列,则直接压入
        items.push(queueElement)
     }else{   //如果不是,则逐个比较优先级,将本元素插入比自己优先级低的元素之前
        var flag=false;
       for(var i=0;i<items.length;i++){
            if(queueElement.priority<items[i].priority){
                    items.splice(i,0,queueElement);
                    flag=true;
                    break;
           }
         }
       if(!flag){
                 items.push(queueElement)    
         }
      }
  }
}

四、集合:用对象来实现

集合是一组无序且唯一的项组成的(不重复)

function Set(){
    var items={};
    this.has=function(value){
        return items.hasOwnProperty(value);
    };
    this.add=function(value){
      if(!this.has(value)){
        items[value]=value;
        return ture;
      }
      return false;
    };
   this.remove=function(value){
      if(this.has(value)){
        delete items[value];
        return ture;
      }
      return false;
    };
   this.values=function(){
     return Object.keys(items);
    }
}

Object.keys 返回一个所有元素为字符串的数组,其元素来自于从给定的object上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致

五、树

二叉搜索树BST:只允许你在左侧节点存储比父节点小的值,在右侧节点存储比父节点大或等于的值。

function BinarySearchTree(){
  var Node=function(key){
     this.key=key;
     this.left=null;
     this.right=null;
   };
  var root=null;
  this.insert()=function(key){  //向树中插入一个键
     var newNode=new Node(key);
     if(root===null){
       root=newNode;
     }else{
         insertNode(root,newNode)
      }
   }
 var insertNode=function(node,newNode){
       if(newNode.key<node.key){
          if( node.left===null){
          node.left=newNode;
           }else{
            insertNode(node.left,newNode)
           }
        }else{
           if( node.right===null){
          node.right=newNode;
           }else{
            insertNode(node.right,newNode)
           }
        }
    }
 }

树的遍历

1、中序遍历

this.inOrderTraverse=function(callback){
   inOrderTraverseNode(root,callback);
}
var inOrderTraverseNode=function(node,callback){
  if(node!==null){
    inOrderTraverseNode(node.left,callback);
    callback(node.key);
    inOrderTraverseNode(node.right,callback);
  }
}

2、先序遍历

this.preOrderTraverse=function(callback){
   preOrderTraverseNode(root,callback);
}
var preOrderTraverseNode=function(node,callback){
  if(node!==null){
    callback(node.key);
    preOrderTraverseNode(node.left,callback);
    preOrderTraverseNode(node.right,callback);
  }
}

3、后序遍历

this.postOrderTraverse=function(callback){
   preOrderTraverseNode(root,callback);
}
var postOrderTraverseNode=function(node,callback){
  if(node!==null){
    callback(node.key);
    postOrderTraverseNode(node.left,callback);
    postOrderTraverseNode(node.right,callback);
  }
}

六、排序和搜索算法

1、冒泡排序

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

改进

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

2、选择排序

找到数据结构中的最小值将其放在第一位,找到第二小的值放在第二位。

function selection(ary){
     var min;
    for (var i=0;i<ary.length-1;i++){
        var min=ary[i];
      for(var j=i;j<ary.length;j++){//找到最小的压入新数组
        if(ary[min]>ary[j]) {
          ary[min]=ary[j]
        }
      }
      if( ary[min]!==ary[i]){
        var temp=ary[i];
        ary[i]=ary[min];
        ary[min]=temp;
      }
    }
  }

3、插入排序:假设第一项已经排序,判断第二项应该插入第一项前面还是原位

function insert(ary){
   var j,temp;
   for(var i=0;i<ary.length;i++){
      j=i;
      temp=ary[i];
      while(j>0&&ary[j-1]>temp){
          ary[j]=ary[j-1];
          j--;
      }
      ary[j]=temp;
    }
}

4、归并排序:把原始数组切分成小的数组,直到每个小数组只有一个位置,接着将小数组归并成大的数组

var mergeSort=function(ary){
  var len=ary.length;
  if(len===1){return ary}
  var mid=Math.floor(length/2);
  left=ary.slice(0,mid);
  right=ary.slice(mid,len);
  return merge(mergeSort(left),mergeSort(right));
}
var merge=function(left,right){
  var result=[],il=0,ir=0;
  while(il<left.length && ir<right.length){
   if(left[il]<right[ir]){
      result.push(left[il++]);
    }else{
     result.push(right[ir++]);
     }
  }
while(il<left.length){
 result.push(left[il++]);
   }

while(ir<lright.length){
 result.push(right[ir++]);
   }
 return result;
}

5、快速排序

    //快速排序算法
	function quickSort(arr){
		if(arr.length <= 1){
			return arr;
		}
		var left = [];
		var right =[];
		var pivotkey = arr[0];
		for(var i=1; i<arr.length; i++){
			if(arr[i] < pivotkey){
				left.push(arr[i]);
			}else{
				right.push(arr[i]);
			}
		}
		return quickSort(left).concat(pivotkey, quickSort(right));
	}

二分搜索

this.binarySearch = function(item){
  var low=0,high=ary.length-1,mid,ele;
  while(low<=high){
    mid=Math.floor((low+high)/2);
    ele=ary[mid];
    if(ele<item){
      low=mid+1;
      }else if(ele>item){
        high=mid-1;
      }else{
        return mid;
      }
  }
   return -1;
}

八:贪心算法

最少硬币找零问题d1=1,d2=5,d3=10,d4=25;

我的实现

function minCoinChange(coins){
    var count=0;//用来存储硬币个数
    var result=[];
    var digui=function(coins)
    {
      if (Math.floor(coins / 25)) {  //大于25美分
        var num=Math.floor(coins / 25);
        count += num;
        coins = coins - 25*num;
        console.log(coins)
        for(var i=0;i<num;i++){
          result.push(25)
        }
        digui(coins)
      } else if (Math.floor(coins / 10)) {//10-25美分
        var num=Math.floor(coins / 10);
        count += num;
        coins = coins - 10*num;
        console.log(coins)
        for(var i=0;i<num;i++){
          result.push(10)
        }
        digui(coins)
      } else if (Math.floor(coins / 5)) { //5-10美分
        count += Math.floor(coins / 5);
        result.push(5)
        coins=coins-5*Math.floor(coins / 5);
        digui(coins)
      } else {   //5美分以下
        count += coins;
        for(var i=0;i<coins;i++){
          result.push(1)
        }
      }
    }
    digui(coins);
    console.log(result)
  }

可以看到,有大量重复代码,并且调用多次递归,四次执行的代码思想都一样

改进:

function MinCoinChange0(coins){
    var coins=coins;
    this.makeChange=function(amount){
      var change=[];
      var total=0;
      for(var i=coins.length;i>=0;i--){
        var coin=coins[i];
        while(total+coin<=amount){
          change.push(coin);
          total+=coin
        }
      }
      return (change)
    }
  }
 var minCoinChange0=new MinCoinChange0([1,5,10,25])
 console.log(minCoinChange0.makeChange(36))

这样就可以随便指定零钱的基数,并且核心代码也比较少。这里,注意用的是while而不是if,If的话就只进入一次,比如找零是20,那么0+10<20;则会给结果数组压入10,继续for循环,coins[2]变为5,再压入5,最后压入1.结果为【10,5,1】

所以必须用while,当第一次0+10<20,total=10,会再次判断10+10<=20.再进入本次循环,压入10,结果为【10,10】

  • 1
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值