const queue = []
// 进队列
queue.push(1)
queue.push(2)
// 出队列
const itme1 = queue.shift()
const itme2 = queue.shift()
const a = {
val: 'a' }
const b = {
val: 'b' }
const c = {
val: 'c' }
const d = {
val: 'd' }
a.next = b
b.next = c
c.next = d
// 遍历
let point = a
while (point) {
console.log(point.val)
point = point.next
}
// 插入
(c-d)中插入d
const e = {
val:'e'}
c.next = e
e.next = d
// 删除 (删除e)
c.next = d
leetcode练习:第83题-删除链表重复元素
var deleteDuplicates = function(head) {
// 定义链表的一个头部的指针
let p = head
while(p && p.next) {
if(p.val === p.next.val) {
// 删除链表的一项
p.next = p.next.next
}else {
// 不相同的时候再移动指针
p = p.next
}
}
return head
};
function myInstanceof (A, B) {
// 遍历链表
let p = A
while (p) {
p = p.__proto__
// B的 prototype 属性是否出现在A实例对象的原型链上
if (p === B.prototype) {
return true
}
}
return false
}
function Foo () {
}
var f = new Foo()
console.log(myInstanceof(f, Foo)); // true
console.log(myInstanceof(f, Object)); // true
// 去重
const arr = [1,1,2,3,4,3]
const arr2 = [...new Set(arr)]
// 判断元素是否在集合中
let set = new Set(arr)
// add 方法
set.add(1)
set.add('text')
set.add({
a:1,b:2})
// has方法
const has =set.has(3)
// delete方法
set.delete(1)
// 获取size 方法
console.log(set.size)
// 求交集
const set2 = new Set([2,3])
const set3 new Set([...set]).filter(item => set2.has(item))
// 求差集
const set2 = new Set([2,3])
const set4 = new Set([...set]).filter(item => !set2.has(item))
// 数组转为set
set2 = new Set([1,2,3])
// 迭代方法 fot ..of
for (let item of set) console.log(item)
for (let item of set.keys())) console.log(item)
for (let item of set.values()) console.log(item)
for (let item of set.entrise()) console.log(item)
补充说明迭代
内置迭代器:
可迭代的对象,都内置以下3种迭代器
entries(): 返回一个迭代器,值为键值对
values(): 返回一个迭代器, 值为集合的值
keys(): 返回一个迭代器,值为集合中的所有键
let userList = [ 'ghostwu', '悟空', '八戒' ];
for ( let name of userList.entries() ) {
console.log( name );
}
let set = new Set( [ 10, 20, 30 ] );
for ( let num of set.entries() ){
console.log( num );
}
let map = new Map( [ [ 'name', 'ghostwu' ], [ 'age', 22 ] ] );
for ( let detail of map.entries() ){
console.log( detail );
}
set
) 删(delete
) 改(set
) 查(get
)const m = new Map()
//增
m.set('a','aaa')
// 删
m.delete('a')
m.clear()
// 改
m.set('a','aaaaa')
// 查
m.get('a')
使用Map取两个数组的交集
var intersection = function(nums1, nums2) {
// new Set(nums1) 去重
return [...new Set(nums1)].filter(item => nums2.includes(item))
};
const tree = {
val: 'a',
children: [
{
val: 'b',
children: [
{
val: 'd',
children: [
]
},
{
val: 'e',
children: [
]
}
]
},
{
val: 'c',
children: [
{
val: 'f',
children: [
]
},
{
val: 'g',
children: [
]
}
]
}
]
}
const dfs =(root) => {
console.log(root.val)
root.children.forEach(dfs)
}
dfs(tree)
打印结果
const bfc = (root) => {
const q = [root]
while (q.length > 0) {
const n = q.shift()
console.log(n.val)
n.children.forEach(child => {
q.push(child)
})
}
}
打印结果:
树中每个节点最多只能有两个子节点
在js中通常用Object来模拟二叉树
const binaryTree = {
val: 1,
left: {
val:2,
left: null,
right: null
},
right: {
val:3,
left: null,
right: null
}
}
根
节点左
子树进行先序遍历右
子树进行先序遍历定义一棵树
const binaryTree = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null,
},
right: {
val: 5,
left: {
val: 7,
left: null,
right: null,
},
right: null,
},
},
right: {
val: 3,
left: null,
right: {
val: 6,
left: null,
right: null,
},
},
};
递归版:
const preorder = root => {
if (!root) return;
console.log(root.val);
preorder(root.left);
preorder(root.right);
};
preorder(binaryTree);
非递归(栈特性):
const preorder = root => {
if (!root) return;
const stack = [root];
while (stack.length) {
const n = stack.pop();
console.log(n.val);
n.right && stack.push(n.right);
n.left && stack.push(n.left);
}
};
preorder(binaryTree);
打印结果:
左
子树进行中序遍历根
接节点右
子树进行中序遍历还是使用binaryTree这个树
递归版实现:
const inorder = root => {
if(!root) return
inorder(root.left)
console.log(root.val)
inorder(root.right)
}
inorder(binaryTree)
非递归版实现:
const inorder = root => {
if (!root) return;
const stack = [];
let p = root;
while (stack.length || p) {
while (p) {
stack.push(p);
p = p.left;
}
const n = stack.pop();
console.log(n.val);
p = n.right;
}
}
inorder(binaryTree)
打印结果:
左
子树进行中序遍历右
子树进行中序遍历根
接节点还是使用binaryTree这个树
递归版实现:
const postorder = (root) => {
if (!root) return;
postorder(root.left);
postorder(root.right);
console.log(root.val);
};
postorder(binaryTree);
非递归版实现:
const inorder = root => {
if (!root) return;
const outputStack = [];
const stack = [root];
while (stack.length) {
const n = stack.pop();
outputStack.push(n);
if (n.left) stack.push(n.left);
if (n.right) stack.push(n.right);
}
while (outputStack.length) {
const n = outputStack.pop();
console.log(n.val);
}
}
inorder(binaryTree)
打印结果:
使用深度优先遍历
const json = {
a: {
b: {
c: 1 } },
d: [1, 2],
};
// 深度优先遍历
const dfs = (n, path) => {
console.log(n, path);
Object.keys(n).forEach((k) => {
dfs(n[k], path.concat(k));
});
};
dfs(json, []);
打印结果
没访问过得相邻节点
挨个进行深度优先遍历const graph = {
0:[1,2],
1:[2],
2:[0,3],
3:[3]
}
使用深度优先遍历
const visited = new Set()
const dfs = n => {
console.log(n)
visited.add(n)
graph[n].forEach(c => {
if(!visited.has(c)) {
dfs(c)
}
})
}
dfs(2)
打印结果
没访问过得相邻节点
入队const bfs = node => {
const visited = new Set()
visited.add(node)
const q = [node]
while (q.length) {
const n = q.shift()
console.log(n)
graph[n].forEach(c => {
if(!visited.has(c)) {
q.push(c)
visited.add(c)
}
})
}
}
bfs(2)
打印结果:
所有的节点都大于等于(最大堆)或小于等于(最小堆)他的节点
js中通常用数组表述堆
左侧子节点的位置是2 * index + 1
右侧子节点的位置是2 * index + 2
父节点的位置是(index - 1) / 2