javascript实现部分数据结构的方法,栈、队列、链表、二叉树、图

<!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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值