二叉树
- 是一棵树
- 每个节点,最多只能有2个子节点
- 树节点的数据结构 { value, left?, right? }
二叉树的遍历
- 前序遍历:root - left - right
- 中序遍历:left - root - right
- 后序遍历:left - right - root
二叉搜索树 BST(Binary Search Tree)
- left(及其后代)value <= root value
- right(及其后台)value >= root value
- 可使用二分法进行快速查找
/**
* @description 二叉树
* @author lsr
*/
export interface ITreeNode {
value: number
left: ITreeNode | null
right: ITreeNode | null
}
const preArr: number[] = []
const inArr: number[] = []
const postArr: number[] = []
/**
* 二叉树前序遍历
* @param node tree node
*/
export function preOrderTraverse(node: ITreeNode | null): number[] {
if (node == null) return []
preArr.push(node.value)
preOrderTraverse(node.left)
preOrderTraverse(node.right)
return preArr
}
/**
* 二叉树中序遍历
* @param node tree node
*/
export function inOrderTraverse(node: ITreeNode | null): number[] {
if (node == null) return []
inOrderTraverse(node.left)
inArr.push(node.value)
inOrderTraverse(node.right)
return inArr
}
/**
* 二叉树后序遍历
* @param node tree node
*/
export function postOrderTraverse(node: ITreeNode | null): number[] {
if (node == null) return []
postOrderTraverse(node.left)
postOrderTraverse(node.right)
postArr.push(node.value)
return postArr
}
/**
* 寻找二叉搜索树中的第 k 小值,使用中序遍历后的结果进行获取
* @param node
* @param k 第几个值
* @returns
*/
export function getKthValue(node: ITreeNode, k: number): number | null {
inOrderTraverse(node)
return inArr[k - 1] || null
}
const tree: ITreeNode = {
value: 5,
left: {
value: 3,
left: {
value: 2,
left: null,
right: null
},
right: {
value: 4,
left: null,
right: null
}
},
right: {
value: 7,
left: {
value: 6,
left: null,
right: null
},
right: {
value: 8,
left: null,
right: null
}
}
}
// 功能测试
console.log('前序遍历----------')
preOrderTraverse(tree)
console.log(preArr) // [5, 3, 2, 4, 7, 6, 8]
console.log('中序遍历----------')
inOrderTraverse(tree)
console.log(inArr) // [2, 3, 4, 5, 6, 7, 8]
console.log('后序遍历----------')
postOrderTraverse(tree)
console.log(postArr) // [2, 4, 3, 6, 8, 7, 5]
const res = getKthValue(tree, 3)
console.log('第3小值', res)
单元测试
/**
* @description 寻找二叉搜索树中的第 k 小值 test
* @author lsr
*/
import {
ITreeNode,
preOrderTraverse,
inOrderTraverse,
postOrderTraverse,
getKthValue
} from '@/01-algorithm/binary-search-tree'
const tree: ITreeNode = {
value: 5,
left: {
value: 3,
left: {
value: 2,
left: null,
right: null
},
right: {
value: 4,
left: null,
right: null
}
},
right: {
value: 7,
left: {
value: 6,
left: null,
right: null
},
right: {
value: 8,
left: null,
right: null
}
}
}
describe('二叉树的三种遍历', () => {
it('前序遍历', () => {
const arr = preOrderTraverse(tree)
expect(arr).toEqual([5, 3, 2, 4, 7, 6, 8])
})
it('中序遍历', () => {
const arr = inOrderTraverse(tree)
expect(arr).toEqual([2, 3, 4, 5, 6, 7, 8])
})
it('后序遍历', () => {
const arr = postOrderTraverse(tree)
expect(arr).toEqual([2, 4, 3, 6, 8, 7, 5])
})
})
describe('寻找二叉搜索树种的第k小值', () => {
it('正常情况', () => {
const res = getKthValue(tree, 3)
expect(res).toBe(4)
})
it('不正常情况', () => {
const res1 = getKthValue(tree, 0)
expect(res1).toBeNull()
const res2 = getKthValue(tree, 100)
expect(res2).toBeNull()
})
})
划重点
- 二叉树,和三种(前序、中序、后序)遍历
- 二叉搜索树的特点:left <= root,right >= root
- 二叉树的搜索价值:可使用二分法进行快速查找