数据结构-二叉查找树

// 节点对象
class TreeNode {
    left: TreeNode | null = null
    right: TreeNode | null = null
    count = 1 // 插入时的次数

    constructor(public data: any) { }
}

// 二叉查找树
class BST {
    root: TreeNode | null = null

    // 二叉树插入,只能插入在叶子节点
    addNode(target: TreeNode) {
        if (!this.root) {
            this.root = target
        } else {
            let curNode = this.root // curNode 进行迭代,与当前节点数值对比,直到找到左节点或右节点为空的节点即可插入
            while (curNode) {
                if (target.data == curNode.data) {
                    curNode.count++
                    break
                } else if (target.data < curNode.data) {
                    if (curNode.left) {
                        curNode = curNode.left

                    } else {
                        curNode.left = target
                        break
                    }
                } else {
                    if (curNode.right) {
                        curNode = curNode.right
                    } else {
                        curNode.right = target
                        break
                    }
                }
            }
        }

    }

    //  递归找到叶子,插入节点
    addNodeRecursive(target: TreeNode) {
        if (!this.root) {
            this.root = target
            return
        }

        const dfs = (node: TreeNode) => {
            if (target.data < node.data) {
                if (node.left) {
                    dfs(node.left)
                } else {
                    node.left = target
                    return
                }
            } else if (target.data > node.data) {
                if (node.right) {
                    dfs(node.right)
                } else {
                    node.right = target
                    return
                }
            } else {
                node.count++
                return
            }
        }

        dfs(this.root)

    }

    //  深度优先搜索,分为先序遍历,中序遍历,后序遍历
    preOrder(cb: (node: TreeNode) => any) {
        let str = ''
        const dfs = (node: TreeNode | null) => {
            if (!node) return

            cb && typeof cb == 'function' && cb(node)

            str += node.data + ' '

            dfs(node.left)
            dfs(node.right)
        }

        dfs(this.root)

        console.log(str)
    }
    middleOrder(cb: (node: TreeNode) => any) {
        let str = ''
        const dfs = (node: TreeNode | null) => {
            if (!node) return

            dfs(node.left)

            cb && typeof cb == 'function' && cb(node)

            str += node.data + ' '

            dfs(node.right)
        }

        dfs(this.root)

        console.log(str)
    }
    postOrder(cb: (node: TreeNode) => any) {
        let str = ''
        const dfs = (node: TreeNode | null) => {
            if (!node) return

            dfs(node.left)

            dfs(node.right)

            cb && typeof cb == 'function' && cb(node)

            str += node.data + ' '

        }

        dfs(this.root)

        console.log(str)
    }

    // 广度优先搜索
    bsf(cb: (node: TreeNode) => any) {
        const queue: TreeNode[] = [] // 借助队列存储最近的一层的所有节点,然后实现广度优先搜索
        if (this.root) {
            queue.push(this.root)
        }

        let str = ''
        while (queue.length) {
            const cur = queue.shift()
            if (cur && cur.left) {
                queue.push(cur.left)
            }
            if (cur && cur.right) {
                queue.push(cur.right)
            }

            if (cur) {
                str += cur.data + " "

                cb && typeof cb == 'function' && cb(cur)
            }

        }
        console.log('广度优先搜索', str)

    }

    // 查找子树的最小节点
    getMinNode(node: TreeNode | null = this.root) {
        let cur = node
        if (!cur) return null

        while (cur.left) {
            cur = cur.left
        }

        return cur
    }

    getMinValue(node: TreeNode | null = this.root) {
        const res = this.getMinNode(node)
        return res ? res.data : null
    }

    // 查找子树的最大节点
    getMaxNode(node: TreeNode | null = this.root) {
        let cur = node
        if (!cur) return null

        while (cur.right) {
            cur = cur.right
        }
        return cur
    }
    getMaxValue(node: TreeNode | null = this.root) {
        const res = this.getMaxNode(node)
        return res ? res.data : null
    }

    // 查找给定数值,递归
    findNodeRecursive(data: any) {

        if (!this.root) return null
        // 最小子任务是比较当前节点与给定值大小
        const dsf = (node: TreeNode): TreeNode | null => {
            if (node.data == data) {
                return node
            } else if (data < node.data) {
                if (!node.left) return null
                return dsf(node.left)
            } else {
                if (!node.right) return null
                return dsf(node.right)
            }
        }

        return dsf(this.root)
    }

    // 查找给定数值的节点,迭代
    findNode(data: any) {
        let cur = this.root

        while (cur) {
            if (cur.data == data) {
                return cur
            } else if (data < cur.data) {
                cur = cur.left
            } else {
                cur = cur.right
            }
        }
        return null
    }

    // 迭代法删除数据,不够简洁
    removeNode(data: any) {
        let cur = this.root
        if (!cur) return

        let parent = cur

        while (true) {
            if (data == cur.data) {
                if (!cur.left && !cur.right) {
                    // 没有子节点
                    if (parent == this.root && cur == parent) {
                        // 删除节点为根节点
                        this.root = null
                    } else {
                        parent.left == cur && (parent.left = null)
                        parent.right == cur && (parent.right = null)
                    }

                } else if (!cur.left) {
                    // 没有左节点
                    if (parent == this.root && cur == parent) {
                        this.root = cur.right
                    } else {
                        parent.right == cur.right
                    }

                } else if (!cur.right) {
                    // 没有右节点
                    if (parent == this.root && cur == parent) {
                        this.root = cur.left
                    } else {
                        parent.left == cur.left
                    }

                } else {
                    // 两个叶子节点,将右子树最小值数据复制到要目标删除节点,然后删除最小值节点
                    const [rightMinNode, parentNode] = getMinAndParentNode(cur.right, cur)! // 右子树最小值节点,以及父节点
                    if (parent == this.root && cur == parent) {
                        this.root.data = rightMinNode.data
                    } else {
                        cur.data = rightMinNode.data
                    }
                    (parentNode.left == rightMinNode) && (parentNode.left = null);
                    (parentNode.right == rightMinNode) && (parentNode.right = null)
                }

                return data

            } else if (data < cur.data) {
                if (!cur.left) return
                parent = cur
                cur = cur.left
            } else {
                if (!cur.right) return
                parent = cur
                cur = cur.right
            }

        }

        function getMinAndParentNode(node: TreeNode, parent: TreeNode) {
            let cur = node
            while (true) {
                if (cur.left) {
                    parent = cur
                    cur = cur.left
                } else {
                    return [cur, parent]
                }
            }
        }
    }

    // 递归删除数据
    removeNodeRecursive(data: any) {
        // 递归函数,node是递归的当前节点,缩小问题规模,data参数是要删除的数据,返回值是经过处理后上个节点的子节点
        const remove = (node: TreeNode | null, data: any) => {
            if (!node) return null
            if (node.data == data) {
                if (node.left && node.right) {
                    // 有左右子树
                    // 找到右子树最小值节点,复制到目标删除节点,删除右最小子节点
                    const rightMinNode = this.getMinNode(node.right)!
                    node.data = rightMinNode.data
                    node.right = remove(node.right, rightMinNode.data)
                    return node
                } else if (!node.right) {
                    // 只有左子树
                    return node.left
                } else if (!node.left) {
                    // 只有右子树
                    return node.right
                } else {
                    return null
                }

            } else if (node.data > data) {
                node.left = remove(node.left, data)
                return node
            } else {
                node.right = remove(node.right, data)
                return node
            }
        }

        this.root = remove(this.root, data)
    }

    getNodeCount(node: TreeNode | null = this.root) {
        let count = 0
        this.bsf((node) => {
            if (node) {
                count++
            }
        })
        return count
    }

    getPathCount(node: TreeNode | null = this.root) {
        let count = 0
        this.bsf((node) => {

            if (node.left && node.right) {
                count += 2
            } else if (!node.left && !node.right) {
                count += 0
            } else {
                count += 1
            }
        })
        return count
    }

    toString() {
        console.log(this.root)
    }
}

const bst = new BST()

const nums = [56, 22, 81, 10, 30, 77, 92]
/*
           56
         /    \
       22      81
      /  \    /  \
    10   30  77   92

*/
nums.forEach(num => {
    const node = new TreeNode(num)

    // bst.addNode(node)
    bst.addNodeRecursive(node)
})
// console.log(bst)

// bst.preOrder() // 56 22 10 30 81 77 92
// bst.middleOrder() // 10 22 30 56 77 81 92
// bst.postOrder() // 10 30 22 77 92 81 56

// bst.bsf()

// console.log('最小节点', bst.getMinNode())
// console.log('最大节点', bst.getMaxNode())
// console.log('指定节点', bst.findNodeRecursive(81))
// console.log('指定节点', bst.findNode(92))
// console.log('删除节点', bst.removeNode(92), bst)
// console.log('使用递归实现的删除节点', bst.removeNodeRecursive(56), bst)
// console.log('getNodeCount', bst.getNodeCount())
// console.log('getPathCount', bst.getPathCount())

// 写一段程序,读取一个大的文本,将单词保存到BST中,显示每个单词出现的次数
let text = `
Sure, here's a short English article for you:

Title: The Impact of Technology on Modern Society

In today's fast-paced world, technology plays a pivotal role in shaping the way we live, work, and interact with one another. From the advent of smartphones to the rise of artificial intelligence, technological advancements have revolutionized nearly every aspect of modern society.

One of the most notable impacts of technology is its influence on communication. With the widespread adoption of social media platforms and messaging apps, people can now connect with others across the globe instantaneously. Whether it's sharing updates with friends and family or collaborating with colleagues on projects, technology has made communication more convenient and efficient than ever before.

Moreover, technology has transformed the way we access information and consume media. With the internet at our fingertips, we have unlimited access to a wealth of knowledge on virtually any topic. From online news articles to educational videos, the internet has democratized information, empowering individuals to learn and grow at their own pace.

In addition to communication and information access, technology has also revolutionized industries such as healthcare, transportation, and entertainment. From telemedicine platforms that enable remote medical consultations to self-driving cars that promise to revolutionize transportation, technological innovations are reshaping the way we approach various aspects of our lives.

However, along with its numerous benefits, technology also presents challenges and ethical dilemmas. Issues such as data privacy, cybersecurity, and the digital divide have become increasingly prevalent in today's tech-driven world. As we continue to embrace new technologies, it's crucial to address these challenges and ensure that the benefits of technology are accessible to all members of society.

In conclusion, technology has become an integral part of modern society, transforming the way we communicate, access information, and live our lives. While its impact is undeniable, it's essential to approach technological advancements with caution and foresight, ensuring that we harness the power of technology for the greater good of humanity.

Feel free to let me know if you need any adjustments or further assistance!
`
const splitReg = /[\w']+/g
const res = text.match(splitReg)
const textBst = new BST()
if (res) {
    res.forEach(word => {
        const node = new TreeNode(word)
        textBst.addNode(node)
    })
}
// console.log(textBst)
const countMap: Record<string, number> = {}
textBst.preOrder((node) => {
    countMap[node.data] = node.count

})
console.log(countMap)



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值