数据结构 笔记

1简介

  1. 程序= 算法+ 数据结构
  2. 数据结构为算法提供服务 , 算法围绕数据结构操作

2复杂度

时间复杂度

​ 就是看代码执行了多少次 , 两个不同的时间复杂度相加 , o(1)+o(n)=o(n),结果等于大的复杂度

​ 例如 : for 为o(n) 嵌套for为 o(n2) o(logN) image-20200829180530197

​ 空间复杂度

​ 代码所占用内存 ,就是声明了多少个变量. 如果为数组,要里面的每个值都要计算进去

3栈

​ 后进先出, 用push pop可模拟

​ vscode自带node调试 , 执行代码可以不用放到html里面 , 打个断点按f5, 可显示每个变量的值

​ 栈的应用

​ 10进制转二进制image-20200829182028236

​ 括号是否闭合 (越靠后的括号,对应的反括号越前) ((((()))))

​ leetcode 20

​ 函数调用(后面的函数, 先执行)

​ callstack 调用堆栈, 函数按执行顺序进入callstackimage-20200829182742870

4队列

​ 先进先出,就跟排队一样

​ 应用场景

​ 排队

​ js异步任务队列

​ 计算最近请求次数 : 计算3000ms内的请求次数

​ LeetCode 933

​ 任务队列

​ js刚执行时, 会丢一个匿名事件到任务队列 , js引擎就执行, 当遇到异步, 会把它交给webapi处理, js引擎依然向后执行 . 当异步的回调有事件 , 会将它放到任务队列 , 以此循环

image-20200830160404411

​ 总结

​ 先进先出 , js以数组模拟队列, 队列常用操作 , push shift queue[0]

5 链表

​ 多个元素组成的列表 , 元素存储不连续 , 用next指针链接在一起image-20200830163602501

​ 与数组的区别

​ 数组插入删除元素,会移动其他元素位置

​ 链表秩序改变next指向就可以了

​ js没有链表 , 可用object来模拟链表

  a = {v=1 }  
  b = {v=2 } 
  c = {v=13 }
  a.next = b    b.next = c 
  //就形成了一个嵌套结构 , 可以称a 为链表
  //遍历链表
  var p =a 
  while(p){
  	console.log(p.v)
  	p = p.next
  }
  //插入值
  x = {v = 77}
  b.next = x   x.next = c
  //删除值
  b.next = c

LeetCode 237 206 2 83 141

js中的原型链

​ 原型链本质是链表 , 以Object构造函数开头的链表

​ 如果A延着原型链能找到B.protyoe , 则A instanceof B 为true

​ 如果A没有x属性 , 会沿着原型链上往上找

面试题1 instanceof原理

  const arr = []
  //遍历链表
  const instanceof = funrion(a,b){
  		let p=a
  		while(p){
  			if(p===b.prototype) {
  				return true
  			}
  			p = p._prote_
  		}
  		return false
  }

image-20200830175129621

​ 遍历链表:使用链表指针获取json节点值image-20200830210410850

6,集合

​ 唯一且无序 , 相当于数组的升级版

​ es6的set就是集合

​ 集合 的常用操作 :去重 判断元素是否在集合中 求交集

  //去重
  	let arr = [1,2,3,3]
  arr=	[...new set(arr)]
  //判断是否在集合中
  	let set = new set(arr)
  	set.has(3)
  //求交集
  	const set2 = new set([2,3])
  	const jiaoji = new set([...set].filter(item=>{st2.has(item)}))

​ leetcode 349

​ es6 set的用法

​ set类似数组 , 没有重复

​ 使用set对象 :new add delete has size

​ 迭代set :多种迭代方法 , set和array互转 , 求交集\差集

	let set = new set()
	set.add()
	set.delete()
	set.has()
	set.size
	//迭代   key和value是一样的
	for(let item in set)
	for(let item in set.key())
	for(let item in set.value())
	for(let [key,value] in set.entries())
	//set和array互转 
	arr= [...set]   arr = Array.form(Set)
	set = new set(arr)
	//交并集
		const jiaoji = new set([...set].filter(item=>{st2.has(item)}))
		const bingji = new set([...set].filter(item=>{!st2.has(item)}))

7字典

​ 字典也是不重复的数据结构 , 以键值对存储 , 相当于对象的升级版

​ es6中 为map

​ 常用操作: 增删改查

  let m = new map()
  //增  m.set('name','小计')
  //删  m.delete('name')
  		m.clear()
  //改  m.set('name','小三')
  //插  m.get('name')

​ leetcode 349 20 1 3 76

8树

​ 1种分层的数据模型

​ 前端 :dom , 级联选择器

​ js中以Object和Array 来构建树

​ 常用操作 : 深度\广度遍历树 , 先中后序遍历

​ 深度优先遍历

​ 先往深处遍历, image-20200831130944851

​ 算法口诀

​ 先访问根节点

​ 在递归children, 对跟节点的children挨个进行深度优先遍历

​ 广度优先遍历

​ 先遍历上层,一层一层遍历image-20200831132434734

​ 算法口诀

​ 新建一对列, 把根节点

	const root = {
		val:1 ,
		children:[{
			val:2
		},{
			val:3
		}
		]
	}
	
	//深度优先遍历
	const dif = (root)=>{
		console.log(root.val)
		//root.children.forEach(item=>dif(item))
		//简化  root.children.forEach(dif)
	}
	//广度优先遍历
	const bfs = (root)=>{
		let p = [root],
		while(p.length>0){
			let a=	p.shift()
			console.log(a)
			a.children.forEach(item=>p.push(item))
		}
	}

二叉树

​ 最多只有两个节点

​ 以Object模拟

​ 遍历

​ 先序 根 左子树先序 右子树先序

​ 中序 左子树中序 根 右子树中序

​ 后序 左子树后序 右子树后序 根

  //二叉树
  	obj = {
  		val=1,
  		left:{
  			val=2
  		}
  		right:{
  			val=3
  		}
  	}
  	//先序
  	let preorder = (obj)=>{
  		if(!obj) return
  		console.log(obj.val)
  		preorder(obj.left)
  		preorder(obj.right)
  	} 
  		//中序	
  	let preorder = (obj)=>{
  		if(!obj) return
  		preorder(obj.left)
  		console.log(obj.val)
  		preorder(obj.right)
  	} 
  		//后序
  	let preorder = (obj)=>{
  		if(!obj) return
  		preorder(obj.left)
  		preorder(obj.right)
  		console.log(obj.val)
  	} 

​ 非递归版

​ LeetCode 104 111 102 94 112

​ 遍历json所有节点值

​ 渲染antd的树组件

9图

​ 由边连接的一组节点

​ js用object和array构建图

​ 图的表示法: 邻接矩阵,邻接表image-20200831161206226image-20200831161114572

​ 常用操作:深度优先和广度优先遍历

​ 深度优先

​ 访问根节点

​ 对没有访问过的节点进行深度优先遍历image-20200831163514831

​ 广度优先

​ 新建队列, 把根节点入队

​ 队头出队并访问

​ 把队头没访问过的相邻节点入队

​ 重复23,直到队列为空image-20200831170647876

	//深度
		const t = {
			A:[B,C]
			C:[B,F]
		}
		const visied = new Set()
		const sd = (index)=>{
			console.log(index)
			visied.add(index)
			t[index].forEach(item=>{
				if(!visied.has(item)){
					sd(item)
				}
			})
		}
	//广度
		const visied = new Set()
		visied.add(A)
		const q = [A]
		while(visied.length){
			const n = q.shift()
			console.log(n)
			t[n].forEach(item=>{
				if(visied.has(item){
					q.push(item)
					visied.add(item)
				})
			})
		}

10堆

​ 一种特殊的完全二叉树

​ 所以节点都大于它的子节点(称最大堆), 所以节点都小于他的子节点(最小堆)image-20200831180955248

​ js中的堆

​ 以数据形似表示堆

​ 左侧子节点 为 index*2+1

​ 右侧子节点 为 index*2+2

​ 父节点位置 (index-1)/2

​ 堆的应用

​ 堆能高效的找出最大值最小值 , 时间复杂(1)

​ 找出第k个最大值最小值

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值