如果给我一个无序的二叉树,那么在不创建新树的情况下对它进行排序的最佳方法是什么?当我说排序时,我的意思是左子树中的所有节点都小于根节点,而右子树中的所有节点都大于根节点。
我很欣赏将无序二叉树变成二叉树的最最佳方法是提取所有节点,然后将它们插入到新树中,但是是否有另一种方法涉及切换原始树中节点的位置,可以通过算法完成?
创建新树的方法当然是要走的路,但作为一种练习,可以就地对二叉树进行排序。
例如,您可以实现冒泡排序,这样所有节点都保持不变,但它们的值会在此过程中交换。
为此,您需要实现按顺序遍历。然后继续重复完整的无序遍历,其中比较两个连续访问的节点的值,如果它们的顺序不正确,则交换它们的值。当顺序遍历不会导致至少一次交换时,将对树进行排序,并且该过程可以停止。
下面是一个JavaScript实现:
它首先生成一个树,其中包含 10 个节点,其随机无符号整数小于 100。树的形状也是随机的(基于每次插入时提供的随机“路径”)
然后如上所述对树进行排序。由于JavaScript支持生成器和迭代器,所以我使用了这种语法,但也可以用回调系统来实现。
它以非常基本的方式显示树(旋转90°,即根在左侧),因为它是在排序操作之前和之后。
class Node {
constructor(value) {
this.value = value;
this.left = this.right = null;
}
}
class Tree {
constructor() {
this.root = null;
}
// Method to add a value as a new leaf node, using the
// binary bits in the given path to determine
// the leaf's location:
addAtPath(value, path) {
function recur(node, path) {
if (!node) return new Node(value);
if (path % 2) {
node.right = recur(node.right, path >> 1);
} else {
node.left = recur(node.left, path >> 1);
}
return node;
}
this.root = recur(this.root, path);
}
*inorder() {
function* recur(node) {
if (!node) return;
yield* recur(node.left);
yield node;
yield* recur(node.right);
}
yield* recur(this.root);
}
toString() {
function recur(node, indent) {
if (!node) return "";
return recur(node.right, indent + " ")
+ indent + node.value + "\n"
+ recur(node.left, indent + " ");
}
return recur(this.root, "");
}
bubbleSort() {
let dirty = true;
while (dirty) {
dirty = false;
let iterator = this.inorder();
// Get first node from inorder traversal
let prevNode = iterator.next().value;
for (let currNode of iterator) { // Get all other nodes
if (prevNode.value > currNode.value) {
// Swap
const temp = prevNode.value;
prevNode.value = currNode.value;
currNode.value = temp;
dirty = true;
}
prevNode = currNode;
}
}
}
}
// Helper
const randInt = max => Math.floor(Math.random() * max);
// Demo:
const tree = new Tree();
for (let i = 0; i < 10; i++) {
tree.addAtPath(randInt(100), randInt(0x80000000));
}
console.log("Tree before sorting (root is at left, leaves at the right):");
console.log(tree.toString());
tree.bubbleSort();
console.log("Tree after sorting:");
console.log(tree.toString());
主要内容:什么是二叉排序树?,使用二叉排序树查找关键字,二叉排序树中插入关键字,二叉排序树中删除关键字,总结前几节介绍的都是有关静态 查找表的相关知识,从本节开始介绍另外一种查找表—— 动态查找表。 动态查找表中做查找操作时,若查找成功可以对其进行删除;如果查找失败,即表中无该关键字,可以将该关键字插入到表中。 动态查找表的表示方式有多种,本节介绍一种使用树结构表示动态查找表的实现方法—— 二叉排序树(又称为 “二叉查找树”)。 什么是二叉排序树? 二叉排序树要么是空 二叉树,要么具有如下特点:
我正在努力实现二叉搜索树。完成实现所需的功能之一是重新平衡功能。 根据规范,该功能的工作方式如下: rebalance() 方法应创建一个平衡树,从而将偏度降低为零。平衡树是指在整个树中,左子树和右子树的大小相差不超过1(即,每个子树也是平衡的)。 为了平衡树,rebalance() 方法应反复将根值移动到较小的子树,并将最小/最大值从较大的子树移动到根,直到树平衡。然后,它应该以递归方式平衡两个
我们已经看到了两种不同的方法来获取集合中的键值对。回想一下,这些集合实现了 map 抽象数据类型。我们讨论的 map ADT 的两个实现是在列表和哈希表上的二分搜索。在本节中,我们将研究二叉查找树作为从键映射到值的另一种方法。 在这种情况下,我们对树中项的确切位置不感兴趣,但我们有兴趣使用二叉树结构来提供高效的搜索。
二叉树查找 思路说明 二叉树查找是一个面对动态数据比较常用的查找算法。本文根据下面地址文章翻译,并根据本人的理解进行适当修改。 原文地址:http://www.laurentluce.com/posts/binary-search-tree-library-in-python/comment-page-1/ 二叉树查找的定义 定义内容可以参阅Wikipedia:http://en.wikipedi
我试图使用队列的链表实现实现二叉搜索树的级别顺序遍历。 我已经检查了二叉查找树的实现,它是好的。队列的链表实现也是正确的。在这里,我试图访问节点并将其子节点排队。然后使用弹出函数实际访问节点。 这最终是通过递归调用完成的。当我运行以下代码时,我以不同的顺序获得输出。
HLOJ 9576,习题7-2 二叉排序树 输入一个整数关键字序列,生成一棵用链式存储结构存储的二叉排序树,对该二叉排序树能进行查找和插入结点的操作,并对该二叉排序树中结点的关键字按递增和递减顺序输出。 要求依次完成以下工作: (1) 以这n个整数生成(建立)一棵用链式存储结构存储的二叉排序树; (2) 按递增顺序输出该二叉排序树中的整数(关键字); (3) 输入一个整数key1,对该二叉排序树进