Smalltalk 语言 二叉搜索树实现实战

Smalltalk阿木 发布于 2025-05-29 9 次阅读


Smalltalk 语言中的二叉搜索树实现实战

二叉搜索树(Binary Search Tree,BST)是一种常见的树形数据结构,它具有以下特性:每个节点包含一个键值(key)、一个指向左子树的指针和一个指向右子树的指针。对于任意节点,其左子树中的所有节点的键值都小于该节点的键值,而其右子树中的所有节点的键值都大于该节点的键值。这种特性使得二叉搜索树在插入、删除和查找操作上具有高效的性能。

Smalltalk 是一种面向对象的编程语言,以其简洁、优雅和动态性著称。本文将围绕 Smalltalk 语言,实现一个二叉搜索树,并通过一系列操作来展示其实战应用。

Smalltalk 环境准备

在开始编写代码之前,我们需要准备一个 Smalltalk 环境。Smalltalk 有多种实现,如 Squeak、Pharo 和 VisualWorks 等。这里我们以 Pharo 作为示例环境。

1. 下载 Pharo 官网提供的最新版本安装包。
2. 安装 Pharo,并启动 Smalltalk 解释器。

二叉搜索树节点定义

在 Smalltalk 中,我们首先定义一个节点类,用于表示二叉搜索树中的节点。

smalltalk
| Node |
Node := Class [
super: Object.
instanceVar: key, left, right.
key: 0.
left: nil.
right: nil.

initialize: aKey [
self key: aKey.
]
]

在这个类中,我们定义了三个实例变量:`key` 表示节点的键值,`left` 和 `right` 分别指向左子树和右子树。

二叉搜索树类定义

接下来,我们定义一个二叉搜索树类,用于管理树中的节点。

smalltalk
| BinarySearchTree |
BinarySearchTree := Class [
super: Object.
instanceVar: root.
root: nil.

initialize [
self root: nil.
]

insert: aKey [
| newNode |
newNode := Node new: aKey.
self insertNode: newNode.
]

insertNode: aNode [
| currentNode |
currentNode := self root.
while [currentNode isNotNil] [
if [aNode key < currentNode key] [
currentNode left isNotNil ifFalse [currentNode left: aNode].
currentNode := currentNode left.
] else [
currentNode right isNotNil ifFalse [currentNode right: aNode].
currentNode := currentNode right.
]
].
]

find: aKey [
| currentNode |
currentNode := self root.
while [currentNode isNotNil] [
if [aKey = currentNode key] [
^ currentNode.
] else [
aKey < currentNode key ifTrue [currentNode := currentNode left] ifFalse [currentNode := currentNode right].
]
].
^ nil.
]

delete: aKey [
| currentNode, parent, successor, successorParent |
currentNode := self root.
parent := nil.
while [currentNode isNotNil] [
if [aKey = currentNode key] [
exit.
] else [
parent := currentNode.
aKey < currentNode key ifTrue [currentNode := currentNode left] ifFalse [currentNode := currentNode right].
]
].
if [currentNode isNil] [
^ self.
].

if [currentNode left isNil and currentNode right isNil] [
if [parent left = currentNode] [
parent left: nil.
] else [
parent right: nil.
]
] else [
if [currentNode left isNotNil and currentNode right isNil] [
if [parent left = currentNode] [
parent left: currentNode left.
] else [
parent right: currentNode left.
]
] else [
successor := currentNode right.
successorParent := currentNode.
while [successor left isNotNil] [
successorParent := successor.
successor := successor left.
].
currentNode key: successor key.
if [successorParent left = successor] [
successorParent left: successor right.
] else [
successorParent right: successor right.
]
]
]
]
]

在这个类中,我们实现了以下方法:

- `initialize`:初始化二叉搜索树,将根节点设置为 `nil`。
- `insert: aKey`:将一个新节点插入到二叉搜索树中。
- `insertNode: aNode`:递归地将一个节点插入到二叉搜索树中。
- `find: aKey`:在二叉搜索树中查找一个键值。
- `delete: aKey`:从二叉搜索树中删除一个键值。

实战应用

现在我们已经实现了二叉搜索树,接下来我们将通过一系列操作来展示其实战应用。

插入节点

smalltalk
bst := BinarySearchTree new.
bst insert: 50.
bst insert: 30.
bst insert: 70.
bst insert: 20.
bst insert: 40.
bst insert: 60.
bst insert: 80.

查找节点

smalltalk
node := bst find: 40.
node key printNl. % 输出:40

删除节点

smalltalk
bst delete: 30.
node := bst find: 30.
node isNil printNl. % 输出:true

遍历二叉搜索树

smalltalk
bst do: [ :node | node key printNl ].
% 输出:20 30 40 50 60 70 80

总结

本文通过 Smalltalk 语言实现了二叉搜索树,并展示了其实战应用。二叉搜索树是一种高效的数据结构,在许多场景下都有广泛的应用。通过本文的学习,读者可以了解到 Smalltalk 语言在实现二叉搜索树方面的优势,并能够将其应用于实际项目中。