树
数组转换为树
/**
* 扁平数据通过 parent 关联, 实现扁平结构转嵌套 tree 结构
input:
[
{ name: '数据1', parent: null, id: 1 },
{ name: '数据2', id: 2, parent: 1 },
{ name: '数据3', parent: 2, id: 3 },
{ name: '数据4', parent: 3, id: 4 },
{ name: '数据5', parent: 4, id: 5 },
{ name: '数据6', parent: 2, id: 6 }
]
output:
[
{
name: '数据1',
parent: null,
id: 1,
children: [
{
name: '数据2',
id: 2,
parent: 1,
children: [
{
name: '数据3',
parent: 2,
id: 3,
children: [
{
name: '数据4',
parent: 3,
id: 4,
children: [
{
name: '数据5',
parent: 4,
id: 5,
children: []
}
]
}
]
},
{
name: '数据6',
parent: 2,
id: 6,
children: []
}
]
}
]
}
]
*/
function listToTree (list) {
}
答案
Tests
深度遍历?
答案
Tests
广度遍历?
答案
Tests
树的先序,中序,后续?
答案
Tests
二叉树的最大深度
/**
* 二叉树的最大深度
* 输入:{value: 1}
* 输出:1
* 输入:{value: 1, left: {value: 2}, right: {value: 3}}
* 输出:2
* 输入:{value: 1, left: {value: 2, left: {value: 3, left: {value: 4}}}}
* 输出:4
*/
function maxDepth (root) {
}
答案
Tests
翻转二叉树
/**
* 翻转二叉树
* 输入:{value: 1, left: {value: 2}, right: {value: 3}}
* 输出:{value: 1, left: {value: 3}, right: {value: 2}}
* 输入:{value: 1, left: {value: 2, left: {value: 3}}, right: {value: 4}}
* 输出:{value: 1, left: {value: 4}, right: {value: 2, right: {value: 3}}}
*/
function invertTree (root) {
}
答案
Tests
红黑树的平衡原理
- 特性:
- 节点是红色或黑色
- 根节点是黑色
- 所有叶子节点(NIL)是黑色
- 红色节点的子节点必须是黑色
- 从根到叶子的所有路径包含相同数量的黑色节点
- 平衡手段:
- 变色
- 左旋
- 右旋
- 时间复杂度:O(logN)
B树和B+树的区别
- B树:
- 所有节点都可以存储数据
- 适合随机访问
- 常用于文件系统
- B+树:
- 只有叶子节点存储数据
- 叶子节点通过链表相连
- 更适合范围查询
- 常用于数据库索引
AVL树与红黑树比较
- AVL树:
- 更严格的平衡(左右子树高度差不超过1)
- 查询更快
- 插入删除代价更大
- 红黑树:
- 平衡条件较宽松
- 插入删除操作更快
- 实际应用更广泛(如STL)
Trie树的应用场景
- 字符串快速检索
- 前缀匹配
- 自动补全
- 拼写检查
- IP路由表查找
208. 实现 Trie (前缀树)**
- 难度:中等
- 考点:前缀树、字符串查找
- 应用场景:搜索提示、自动完成
o(n)
class Trie {
data: string[] = []
insert (word: string): void {
this.data.push(word)
}
search (word: string): boolean {
return this.data.includes(word)
}
startsWith (prefix: string): boolean {
return this.data.some(i => i.startsWith(prefix))
}
}
o(1)
class TrieNode {
// @ts-error
// eslint-disable-next-line no-use-before-define
children: Map<string, TrieNode> = new Map()
isEndOfWord = false
}
class Trie {
root: TrieNode = new TrieNode()
insert (word: string): void {
let currentNode = this.root
for (const char of word) {
if (!currentNode.children.has(char)) {
currentNode.children.set(char, new TrieNode())
}
currentNode = currentNode.children.get(char)
}
currentNode.isEndOfWord = true
}
traverse (word: string): TrieNode | null {
let currentNode = this.root
for (const char of word) {
if (!currentNode.children.has(char)) {
return null
}
currentNode = currentNode.children.get(char)
}
return currentNode
}
search (word: string): boolean {
const node = this.traverse(word)
return node !== null && node.isEndOfWord
}
startsWith (prefix: string): boolean {
const node = this.traverse(prefix)
return node !== null
}
}