这是我的家庭作业问题,我试图解决它只是需要有人看,告诉我,如果我正确或正确的做法..
动态设定操作UNION将两个不相交的组S1和S2作为输入,并返回由S1和S2的所有元素组成的组S = S1 U S2。集合S1和S2通常由操作破坏。演示如何使用合适的列表数据结构在O(1)时间内支持UNION
我正在考虑有两个链接列表可以在常量时间内完成,但为此我们需要记住一个指向列表的第一个(头部)和最后一个(尾部)元素的指针。 struct node { char * word; struct node * next; } struct Set { struct node * head; struct node * tail; } 对于头指针旁边的每个列表,我们还会保留一个尾指针。 在O(1)时间内支持并集操作:假设我们有两个集合S1和S2。
PSEUDO-CODE:
node* Union(Set S1,Set S2){
S1.tail->next = S2.head;
S1.tail = S2.tail;
Remove S2 from the list of sets;
return S1;
}
我的方法正朝着正确的方向发展吗?
答案 0 :(得分:1)
以防万一我们手头没有指针(实际上是链接列表的常见情况......),我们不能UNION O(1)中的两个列表,因为我们必须遍历其中一个列表来获取它的尾指针,它需要O(n)。
在这种情况下,只有两个头指针,"合适的列表数据结构"必须是双循环链表。我们断开 LIST_1的头元素与其下一个元素之间的链接,并断开 LIST_2的head元素与其prev元素之间的链接。然后我们连接两个头元素并连接另外两个元素。因此,我们得到另一个双循环链表,并且"指针流"被保留(这就是为什么我们不应该将LIST_2的头部元素与其下一个元素断开)。
答案 1 :(得分:0)
是的,这与我采取的方法相同。
S1:
A1->A2->A3
S2:
B1->B2->B3
Tail node of S1 (A3) linked to head node of S2 (B1)
S1US2:
A1->A2->A3*->*B1->B2->B3
答案 2 :(得分:0)
在您提到的问题中,我们可以使用任何合适的列表数据结构(给出的答案也考虑了指向尾巴的指针,除非您要使用单链接列表来完成此操作,否则不必这样做)在O(1)中,当我们讨论链表时,通常只考虑头节点的概念,因此我们将使用双循环链表。现在我们必须加入这两个集合,以便我们可以执行以下操作以在O(1)中实现它
(headS1->prev)->next = headS2;
temp = headS1->prev;
(headS2->prev)->next = headS1 ;
headS1->prev = headS2->prev ;
headS2->prev = temp;