Arrays 列出两个列表中出现的元素?
给定两个已排序的数组(当然没有重复的数组),是否有方法查找并打印两个数组中出现的所有元素 我知道是否可以通过迭代一个数组并构建一个哈希表,然后迭代另一个数组并查找构建的表来获取。但这需要一个O(n)的空间 我试着看看是否有这样一种方法,它需要恒定的额外空间,并且只需要对每个数组迭代不超过一次。可能吗Arrays 列出两个列表中出现的元素?,arrays,algorithm,sorting,binary-search-tree,Arrays,Algorithm,Sorting,Binary Search Tree,给定两个已排序的数组(当然没有重复的数组),是否有方法查找并打印两个数组中出现的所有元素 我知道是否可以通过迭代一个数组并构建一个哈希表,然后迭代另一个数组并查找构建的表来获取。但这需要一个O(n)的空间 我试着看看是否有这样一种方法,它需要恒定的额外空间,并且只需要对每个数组迭代不超过一次。可能吗 现在,如果上述问题是可能的,如果两个排序列表存储在两个二进制搜索树中,那么在共犯限制下,相同的方法是否仍然适用?对于数组,执行与合并操作等效的操作,但不输出。在合并过程中,将检测到任何重复项。这将涉
现在,如果上述问题是可能的,如果两个排序列表存储在两个二进制搜索树中,那么在共犯限制下,相同的方法是否仍然适用?对于数组,执行与合并操作等效的操作,但不输出。在合并过程中,将检测到任何重复项。这将涉及每个列表只通过一次,并将在到达任一列表的末尾时立即终止 二叉搜索树可以使用堆栈进行迭代遍历,但最坏的情况是堆栈空间为O(n)。Morris遍历(进行web搜索)可以在不使用堆栈的情况下遍历二叉树,通过更改和恢复树中的链接,时间复杂度为O(n)(大多数节点每次都会访问多次,但n的倍数的时间开销仍然是时间复杂度O(n))。典型的Morris遍历函数作用于整个树。这将需要更改,以便它按顺序返回每个节点,以便可以使用类似合并的逻辑来检查重复项。我为此编写了一些测试代码,以便在您陷入困境时提供帮助 按顺序遍历二叉树时,每个当前节点都有一个前置节点,该节点按顺序出现在当前节点之前。前置节点将有一个空的“右”指针。在Morris遍历过程中,每个前置节点的“右”指针从null更改为指向其后续节点的指针。最终,当到达前置节点时,跟随它的右指针到达其后续节点,然后后续节点的前置节点的右指针恢复为null 因为已经2天了,这里是Morris遍历函数的示例代码,该函数返回一个指向每个节点的指针。部分逻辑位于main()的for循环中,该循环在再次调用遍历函数之前将返回的指针向右推进(另一种方法是使用向右推进的helper函数,然后调用主遍历函数):
#包括
#包括
/*二叉树节点*/
类型定义结构BTNODE_
{
结构BTNODE_*left;
结构BTNODE_*right;
int数据;
}BTNODE;
/*无栈遍历二叉树*/
/*初始输入参数是指向根的指针*/
/*cur的前身是最大值left->right->right->right->right*/
BTNODE*遍历(BTNODE*cur)
{
BTNODE*pre;
如果(cur==NULL)
返回(空);
while(cur!=NULL){
/*如果是分支的左端,则返回*/
如果(当前->左==NULL)
返回(cur);
/*前进到cur的前身*/
pre=cur->left;
while(pre->right!=NULL&&pre->right!=cur)
pre=pre->right;
/*如果分支右端,则更改pre->right=cur*/
/*向左转*/
如果(预->右==NULL){
前->右=当前;
cur=cur->left;
/*否则返回cur,因此恢复pre->right=NULL*/
/*返回*/
}否则{
pre->right=NULL;
返回(cur);
}
}
返回(空);
}
BTNODE*newbtNode(int数据)
{
BTNODE*BTNODE=(BTNODE*)malloc(sizeof(BTNODE));
btNode->left=NULL;
btNode->right=NULL;
btNode->data=数据;
返回(btNode);
}
int main()
{
BTNODE*cur;
/*创建一个15元素的二叉树*/
BTNODE*root=newbtNode(8);
根->左=新节点(4);
根->左->左=新节点(2);
根->左->左->左=新节点(1);
根->左->左->右=新节点(3);
根->左->右=新节点(6);
根->左->右->左=新节点(5);
根->左->右->右=新节点(7);
根->右=新节点(12);
根->右->左=新节点(10);
根->右->左->左=新节点(9);
根->右->左->右=新节点(11);
根->右->右=新节点(14);
根->右->右->左=新节点(13);
根->右->右->右=新节点(15);
对于(cur=root;cur;cur=cur->right){
cur=穿越(cur);
printf(“%2d”,cur->data);
}
返回0;
}
对于数组,执行与合并操作等效的操作,但不输出。在合并过程中,将检测到任何重复项。这将涉及每个列表只通过一次,并将在到达任一列表的末尾时立即终止
二叉搜索树可以使用堆栈进行迭代遍历,但最坏的情况是堆栈空间为O(n)。Morris遍历(进行web搜索)可以在不使用堆栈的情况下遍历二叉树,通过更改和恢复树中的链接,时间复杂度为O(n)(大多数节点每次都会访问多次,但n的倍数的时间开销仍然是时间复杂度O(n))。典型的Morris遍历函数作用于整个树。这将需要更改,以便它按顺序返回每个节点,以便可以使用类似合并的逻辑来检查重复项。我为此编写了一些测试代码,以便在您陷入困境时提供帮助
按顺序遍历二叉树时,每个当前节点都有一个前置节点,该节点按顺序出现在当前节点之前。前置节点将有一个空的“右”指针。在Morris遍历过程中,每个前置节点的“右”指针从null更改为指向其后续节点的指针。最终,当到达前置节点时,它是右指针
#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;
}
set<int> s1 = {1, 2, 4, 5};
set<int> s2 = {0, 2, 4, 7};
vector<int> v;
set_intersection(s1.begin(), s1.end(),
s2.begin(), s2.end(),
back_inserter(v));
for (auto i : v)
cout << i << '\n';
2
4