<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//栈
var Stack = function() {
var items = []
this.ipush = function(ele) {
items.push(ele)
}
this.pop = function(ele) {
items.pop()
}
this.getitem = function() {
return items
}
}
//使用栈写的10进制转2进制例子
var tenToTwo = function(num) {
var stack = new Stack()
while(num>0) {
stack.ipush(num % 2)
num = Math.floor(num/2)
}
return stack.getitem().reverse().toString().replace(/,/g,'')
}
//队列:击鼓传花
// 队列的类没有实现,用数据方法就可以实现,push,pop,shift,unshift,splice(n,0,ele)中间插入
var Jigu = function (arr,num) {
// arr = []
while(arr.length > 1) {
for(let i = 1;i< num;i++) {
let front = arr[0]
arr.shift()
arr.push(front)
}
arr.shift()
}
return arr[0]
}
// 链表
var lianbiao = function() {
this.head = null
var length = 0
var Node = function(ele) {
this.element = ele
this.next = null
}
// 添加
this.append = function(ele) {
var node = new Node(ele)
if(this.head == null) {
this.head = node
} else {
var current = this.head
while(current.next) {
current = current.next
}
current.next = node
}
length++
} // 插入
this.insert = function(num,ele) {
var node = new Node(ele)
if(num == 0) {
node.next = this.head
this.head = node
} else {
var current= this.head
var time = 0
while(time < num-1) {
current = current.next
time ++
}
var nextEle = current.next
node.next = nextEle
current.next = node
}
length++
}
// 移除某个下标元素
this.removeAt = function(position) {
if(position < 0 || position > length-1) {
return -1
}
if(position == 0) {
this.head = this.head.next
} else {
var time = 0
var current = this.head
var pre = null
while(time < position) {
pre = current
current = current.next
time++
}
pre.next = current.next
}
length --
}
// 找下标
this.indexOf = function(ele) {
var time = 0
var current = this.head
while(time < length) {
if(current.element == ele){
return time
}
current = current.next
time ++
}
return -1
}
// 删除特定元素
this.remove = function(ele) {
var index = this.indexOf(ele)
if(index > 0) {
this.removeAt(index)
}
}
this.getHead = function() {
return this.head
}
}
var li = new lianbiao()
li.append('a')
li.append('b')
li.append('c')
li.append('d')
li.insert(0,'head')
li.insert(3,'mid')
li.removeAt(0)
li.removeAt(2)
// 二叉树
var Tree = function() {
var root = null
var node = function(value) {
this.value = value
this.left = null
this.right = null
}
var insertValue = function(node, newNode) {
if(node == null) {
node = newNode
} else {
if(newNode.value > node.value){
if(node.right == null) {
node.right = newNode
} else {
insertValue(node.right, newNode)
}
} else if(newNode.value < node.value) {
if(node.left == null) {
node.left = newNode
} else {
insertValue(node.left, newNode)
}
}
}
}
// 二叉树插入
this.insert = function(value) {
var newNode = new node(value)
if(root == null) {
root = newNode
} else {
insertValue(root, newNode)
}
}
var traverse = function(node, callback) {
if(node == null) { return }
// callback(node.value) // 前序遍历
traverse(node.left, callback)
// callback(node.value) // 中序遍历
traverse(node.right, callback)
callback(node.value) // 后序遍历
}
// 二叉树遍历
this.traverse = function(cb) {
traverse(root, cb)
}
var min = function(node) {
if(node == null) return null
while(node && node.left) {
node = node.left
}
return node.value
}
// 获取最小值
this.min = function() {
return min(root)
}
var max = function(node) {
if(node == null) return null
while(node && node.right) {
node = node.right
}
return node.value
}
// 获取最大值
this.max = function() {
return max(root)
}
// 树结构最头疼的就是移除节点 --头疼拉夫斯基
var removeNode = function(node, value) {
if(node == null) return null
if(value > node.value) {
// 向右找
node.right = removeNode(node.right, value)
return node
} else if(value < node.value) {
// 向左找
node.left = removeNode(node.left, value)
return node
} else {
// 删除当前元素
if(node.left == null && node.right == null) {// 左右节点皆为空
return null
} else if(node.left == null) { // 右节点为空
node = node.right
return node
} else if(node.right == null) { // 左节点为空
ndoe = node.left
return node
} else { // 左右节点都不为空
// 经过各种数学推导得出结论:要替换为右侧子树的最小节点
nodeMinValue = min(node.right) // 获取右子数的最小节点的值
node.value = nodeMinValue // 当前节点替换为最小值
node.right = removeNode(node.right, nodeMinValue) // 删除右子树
return node
}
}
}
this.remove = function(value) {
root = removeNode(root, value)
}
// 获取二叉树
this.getTree = function() {
return root
}
}
// test
var tree = new Tree()
tree.insert(8)
tree.insert(2)
tree.insert(3)
tree.insert(9)
tree.insert(1)
tree.insert(10)
var cb = function(value) {
console.log('value-: ',value)
}
// 递归
// var time = 0
// var digui = function () {
// if(time >5) return
// console.log(time)
// time ++
// digui()
// }
// 图
var Graph = function() {
// 存储顶点
var vertices = []
// 边
var adjList = {}
// 添加点
this.addVertex = function(v) {
vertices.push(v)
adjList[v] = []
}
// 添加边
this.addEdge = function(a, b) {
adjList[a].push(b)
adjList[b].push(a)
}
// white 未被发现
// grey 已发现未探索
// black 已探索
var initColor = function() {
var color = {}
vertices.forEach(item => {
color[item] = 'white'
})
return color
}
this.bfs = function(v, callback) {
var color = new initColor()
var queue = []
queue.push(v)
while(queue.length > 0) {
let point = queue.shift()
let bian = adjList[point]
bian.forEach(value => {
if(color[value] == 'white') {
queue.push(value)
color[value] = 'grey'
}
})
color[point] = 'black'
if(callback) {
callback(point)
}
}
}
this.BFS = function(v, callback) {
var color = initColor()
var d = {}
var pred = {}
vertices.forEach(item => {
d[item] = 0
pred[item] =null
})
var queue = []
queue.push(v)
while(queue.length > 0) {
let point = queue.shift()
let bian = adjList[point]
bian.forEach(value => {
if(color[value] == 'white') {
queue.push(value)
color[value] = 'grey'
// 设置回溯点
pred[value] = point
d[value] = d[point] + 1
}
})
color[point] = 'black'
if(callback) {
callback(point)
}
}
return {
pred: pred,
d: d
}
}
// 求最短路径
this.zuiduan = function(from, to) {
var pred = this.BFS('A').pred
console.log(pred)
var arr = []
var v = to
while(v != from) {
arr.push(v)
v = pred[v]
}
arr.push(v)
return arr.reverse().toString()
}
// 打印出来
this.print = function() {
var s = ''
for(let i = 0; i < vertices.length; i++) {
let v = vertices[i]
let x = adjList[v]
s += v + '=>'
for(let j = 0; j < x.length; j++) {
s += x[j]
}
s += '\n'
}
console.log(s)
}
}
var graph = new Graph()
graph.addVertex('A')
graph.addVertex('B')
graph.addVertex('C')
graph.addVertex('D')
graph.addVertex('E')
graph.addVertex('F')
graph.addEdge('A', 'B')
graph.addEdge('A', 'C')
graph.addEdge('A', 'D')
graph.addEdge('E', 'B')
graph.addEdge('F', 'B')
graph.addEdge('C', 'D')
</script>
</body>
</html>
javascript实现部分数据结构的方法,栈、队列、链表、二叉树、图
最新推荐文章于 2021-07-30 14:40:31 发布