// 节点对象
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)
数据结构-二叉查找树
于 2024-05-11 00:10:42 首次发布