arrays - 列出出现在两个列表中的元素?

标签 arrays algorithm sorting binary-search-tree

给定两个排序数组(当然没有重复),有没有办法找出并打印出现在两个数组中的所有元素?

我知道是否可以通过迭代一个数组并构建一个哈希表,然后迭代另一个数组并查找构建的表来获得。但这需要 O(n) 的空间。

我正在尝试看看是否有这样一种方法需要不断增加额外空间,并且只需要对每个数组进行不超过一次的迭代。可能吗?

现在如果上述问题是可能的,如果两个排序列表存储在两个二叉搜索树中,那么在给定共谋限制的情况下,相同的方法是否仍然适用?

最佳答案

对于数组,执行与合并操作等效的操作,但没有输出。在合并过程中,将检测到任何重复项。这将只涉及每个列表的一次传递,并且将在到达任一列表的末尾时立即终止。

一棵二叉搜索树可以使用栈来迭代遍历,但最坏情况下的栈空间是O(n)。莫里斯遍历(进行网络搜索)可以在不使用堆栈的情况下遍历二叉树,并且通过更改和恢复树中的链接以 O(n) 的时间复杂度(大多数节点将被访问多次,但时间开销是倍数) n 的时间复杂度仍为 O(n))。典型的 Morris 遍历函数在整棵树上运行。这将需要更改,以便它按顺序返回每个节点,以便可以使用类似合并的逻辑来检查重复项。我为此编写了一些测试代码,以便在您遇到困难时提供帮助。

当按顺序遍历二叉树时,每个当前节点都有一个前驱节点,即按顺序出现在当前节点之前的节点。前驱节点将有一个空的“右”指针。在 Morris 遍历期间,每个前驱节点的“右”指针从 null 更改为指向它的后继节点。最终到达一个前驱节点时,跟随它的右指针到达它的后继节点,然后后继节点的前驱节点的右指针恢复为空。

已经 2 天了,下面是 Morris 遍历函数的示例代码,该函数返回一个指向每个节点的指针。部分逻辑在 main() 的 for 循环中,它在再次调用遍历函数之前将返回的指针向右推进(另一种方法是有一个向右推进的辅助函数,然后调用主遍历函数) :

#include<stdio.h>
#include<stdlib.h>

/* binary tree node */
typedef struct BTNODE_
{
    struct BTNODE_* left;
    struct BTNODE_* right;
    int data;
}BTNODE;

/* traverse binary tree without stack */
/* initial input parameter is pointer to root */
/* predecessor of cur is largest value < cur */
/* predecessor of cur = cur->left->right->right->right ... */
BTNODE * MorrisTraversal(BTNODE *cur)
{
BTNODE *pre;
    if(cur == NULL)
        return(NULL);
    while(cur != NULL){
        /* if left end of branch, return */
        if(cur->left == NULL)
            return(cur);
        /* advance pre to predecessor of cur */
        pre = cur->left;
        while(pre->right != NULL && pre->right != cur)
            pre = pre->right;
        /* if right end of branch, change pre->right = cur */
        /*  and advance cur left */
        if(pre->right == NULL){
            pre->right = cur;
            cur = cur->left;
        /* else back at cur, so restore pre->right = NULL */
        /*  and return */
        } else {
            pre->right = NULL;
            return(cur);
        }
    }
    return(NULL);
}

BTNODE* newbtNode(int data)
{
BTNODE* btNode = (BTNODE*) malloc(sizeof(BTNODE));
    btNode->left = NULL;
    btNode->right = NULL;
    btNode->data = data;
    return(btNode);
}

int main()
{
BTNODE *cur;
/* create a 15 element binary tree */
BTNODE *root = newbtNode(8);
    root->left                = newbtNode( 4);
    root->left->left          = newbtNode( 2);
    root->left->left->left    = newbtNode( 1);
    root->left->left->right   = newbtNode( 3);
    root->left->right         = newbtNode( 6);
    root->left->right->left   = newbtNode( 5);
    root->left->right->right  = newbtNode( 7);
    root->right               = newbtNode(12);
    root->right->left         = newbtNode(10);
    root->right->left->left   = newbtNode( 9);
    root->right->left->right  = newbtNode(11);
    root->right->right        = newbtNode(14);
    root->right->right->left  = newbtNode(13);
    root->right->right->right = newbtNode(15);
    for(cur = root; cur; cur = cur->right){
        cur = MorrisTraversal(cur);
        printf("%2d ", cur->data);
    }
    return 0;
}

关于arrays - 列出出现在两个列表中的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44711435/

相关文章:

arrays - 使用字典中的键创建数组,并按字典值排序

PHP 无论如何我可以在函数的返回值上模拟数组运算符

C - 将数组发送到函数而不声明它

algorithm - 具有 2 个约束(权重和颜色)的最短路径

c# - 无法解决这个 html 生成难题

使用自定义函数的 C++ std::sort

c++ - 将一个 vector 拆分为 n 个子 vector (反弹)

javascript - 如何在vueJs中使用forEach?

algorithm - 关系数据库中的时间表建模

python - 保持先前未排序列表中的值之间的关联?