跳到主要内容

数据结构

二叉树

满二叉树

一个二叉树,每一层的结点数都达到了最大值。

完全二叉树

一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树

二叉查找树

左结点小于根结点,右结点大于根结点。子树也如此。

平衡二叉树

左右子树的高度差不能大于1。子树也如此。

通过旋转结点来保持二叉树的平衡。

二叉树的创建

class Node {
constructor(data, left, right) {
Object.assign(this, {
data,
left,
right
})
}
}

class BST {
constructor() {
this.root = null
}

insert(data) {
let node = new Node(data)
if (!this.root) {
this.root = node
}
else {
let current = this.root
while (true) {
if (data < current.data) {
if (current.left) {
current = current.left
}
else {
current.left = node
break
}
}
else {
if (current.right) {
current = current.right
}
else {
current.right = node
break
}
}
}
}
}
}


// 使用
let tree = new BST()
tree.insert(10)
tree.insert(20)
tree.insert(15)
tree.insert(12)
tree.insert(5)

树的遍历

二叉树的递归遍历

// 递归的先序遍历
function preOrder (node, cb) {
if (node) {
cb(node.data)
preOrder(node.left, cb)
preOrder(node.right, cb)
}
}

// 递归的中序遍历
function inOrder (node, cb) {
if (node) {
inOrder(node.left, cb)
cb(node.data)
inOrder(node.right, cb)
}
}

// 递归的后序遍历
function postOrder (node, cb) {
if (node) {
postOrder(node.left, cb)
postOrder(node.right, cb)
cb(node.data)
}
}

二叉树的非递归遍历

// 非递归的先序遍历
function preOrder(node) {
let stack = [], res = []
stack.push(node)
while (stack.length > 0) {
let node = stack.pop()
res.push(node.data)
if (node.right) {
stack.push(node.right)
}
if (node.left) {
stack.push(node.left)
}
}
return res
}

// 非递归的中序遍历
function inOrder(node) {
let stack = [], res = []
while (stack.length > 0 || node) {
if (node) {
stack.push(node)
node = node.left
} else {
node = stack.pop()
res.push(node.data)
node = node.right
}
}
return res
}

// 非递归的后序遍历 方法1
function postOrder(node, cb) {
let stack = []
let res = []
while (stack.length > 0 || node) {
res.unshift(node.data)
if (node.right) {
stack.push(node.right)
}
if (node.left) {
stack.push(node.left)
}
node = stack.pop()
}
return res
}

// 方法2,其实就是在先序遍历的基础上把返回数组进行reverse处理
function postOrder(node) {
let stack = [], res = []
stack.push(node)
while (stack.length > 0) {
let node = stack.pop()
res.push(node.data)
if (node.left) {
stack.push(node.left)
}
if (node.right) {
stack.push(node.right)
}
}
return res.reverse()
}

深度优先遍历

递归的深度优先遍历

function DFS(node, nodeList = []) {
if (node !== null) {
nodeList.push(node)
let children = node.children
for (let i = 0; i < children.length; i++) {
DFS(children[i], nodeList)
}
}
return nodeList
}

非递归的深度优先遍历

function DFS(node) {
let nodes = []
let stack = []
stack.push(node)

while(stack.length) {
let item = stack.pop()
let children = item.children
nodes.push(item)
// node = [] stack = [parent]
// node = [parent] stack = [child3,child2,child1]
// node = [parent, child1] stack = [child3,child2,child1-2,child1-1]
// node = [parent, child1, child1-1] stack = [child3,child2,child1-2]
for (let i = children.length - 1; i >= 0; i--) {
stack.push(children[i])
}
}
return nodes
}

广度优先遍历

function BFS(node) {
let nodes = []
let stack = []
stack.push(node)
while(stack.length) {
let item = stack.shift()
let children = item.children
nodes.push(item)
// 队列,先进先出
// nodes = [] stack = [parent]
// nodes = [parent] stack = [child1,child2,child3]
// nodes = [parent, child1] stack = [child2,child3,child1-1,child1-2]
// nodes = [parent,child1,child2] stack = [child3, ...]
for (let i = 0; i < children.length; i++) {
stack.push(children[i])
}
}

return nodes
}

链表

链表的建立

class Node {
constructor(data) {
this.next = null
this.data = data
}
}

class List {
constructor() {
this.head = null
this.length = 0
}

append(data) {
let node = new Node(data)
if (this.head) {
let current = this.head
while(current.next !== null) {
current = current.next
}
current.next = node
}
else {
this.head = node
}
this.length++
}

insert(data, position) {
let node = new Node(data)
if (position >= 0 && position <= this.length) {
let currentNode = this.head
let previousNode = null
let index = 0
if ( position === 0 ) {
node.next = this.head
this.head = node
}
else {
while( index++ < position ) {
previousNode = currentNode
currentNode = currentNode.next
}
previousNode.next = node
node.next = currentNode
}
this.length++
}
}

size() {
return this.length
}

isEmpty() {
return this.length === 0
}
}

let list = new List()

反转单向链表

function reverseList(list) {
let head = list.head
let currentNode = head
let pre
while (currentNode) {
let nextNode = currentNode.next
currentNode.next = pre
pre = currentNode
currentNode = nextNode
}
return pre
}