【问题标题】:Find the most optimal solution for sorting data organized in arrays and in AVL trees找到对以数组和 AVL 树组织的数据进行排序的最佳解决方案
【发布时间】:2018-06-14 21:39:04
【问题描述】:

这是我在数据结构考试中遇到的以下练习题。我们想从两组大小为 n 的数字 A 和 B 中得到有序的整数序列。

  1. A 和 B 被组织成未排序的数组。
  2. A 和 B 被组织成数组,其中只有第一个被排序。
  3. A 和 B 被组织成 AVL 树。

在每种情况下,我都希望将结果存储在另一个大小为 2*n 的数组 C 中。

对于第一种情况,我认为只需将所有元素复制到第二个数组中,这将花费 O(2n),然后使用快速排序将它们全部排序在一起,这将花费 O(2nlog2n)。

对于第二种情况,有没有更快的方法,还是我应该像以前一样将它们全部复制和排序?

我也不知道如何处理第三种情况。

【问题讨论】:

  • 对于第二种情况,你不能对数组B进行排序,它是nlogn时间内未排序的数组,然后对其应用合并两个排序的数组A和B算法。对于第三种情况,只需在树上应用树遍历并将数组的元素继续存储在列表中,然后对列表进行排序。
  • 所以对于第三种情况应用顺序树遍历第一棵树并复制到一个数组并应用顺序树遍历第二棵树并复制到另一个数组然后合并两个排序数组A B. 听起来对吗??
  • 这听起来很对,没错。总时间复杂度将在一天结束时为 O(n)。

标签: arrays sorting data-structures time-complexity avl-tree


【解决方案1】:
  1. 您的解决方案是渐近最优的。
  2. 就地排序 B。然后将两个列表简单地合并到最终列表中。对 B 数组进行排序的复杂度为 O(n log n),合并的复杂度为 O(2n)。
  3. 开始对两棵树进行非递归中序遍历,使用显式堆栈来维护状态,并合并到单个输出数组中。复杂度为 O(2n)。

对于非递归中序树遍历,见https://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion/

基本上,您修改该代码以创建具有方法的tree_traversal 类:

  • isAtEnd - 如果您遍历了整棵树,则返回 true
  • peek - 返回树中的当前项
  • next - 移动到树中的下一项

为每棵树实例化一个中序遍历,然后进行标准合并。比如:

a = new int[2*n]; // allocate output array
ix = 0; // output index
t1 = new tree_traversal(tree_a);
t2 = new tree_traversal(tree_b);
while (!t1.isAtEnd() && !t2.isAtEnd())
{
    if (t1.peek() < t2.peek())
    {
        a[ix] = t1.peek();
        t1.next();
    }
    else
    {
        a[ix] = t2.peek();
        t2.next();
    }
    ++ix;
}
// at this point, you've reached the end of one tree
// empty the other
while (!t1.isAtEnd())
{
    a[ix] = t1.peek();
    t1.next();
    ++ix;
}
while (!t2.isAtEnd())
{
    a[ix] = t2.peek();
    t2.next();
    ++ix;
}

【讨论】:

    猜你喜欢
    • 2010-09-07
    • 1970-01-01
    • 2012-04-27
    • 2011-04-12
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多