《算法导论》10.2-6 动态集合操做Union以两个不相交集合S1和S2做为输入,并返回集合S = S1∪S2。该操做一般会破坏集合S1和S2。试说明如何选用一种合适的表类数据结构,来支持O(1)时间的Union操做。html
O(1)时间能干吗?不能移动元素,只能改改指针,因此采用链表最合适,这道题采用单链表就够了。算法
我在以前定义的SingleLinkedList类型里面声明一个friend function。注意声明为friend 的class or function不能够是template,必须是实例化类型或方法,因此用friend SingleLinkedList Union<Object>(SingleLinkedList&& lhs,SingleLinkedList&& rhs);
而不是friend SingleLinkedList Union(SingleLinkedList&& lhs, SingleLinkedList&& rhs);
。数据结构
//将模板函数Union声明为class SingleLinkedList的友元函数 template<typename Object> class SingleLinkedList; //needed for parameters in Union //forward declarations needed for friend declarations in SingleLinkedList template<typename Object> SingleLinkedList<Object> Union(SingleLinkedList<Object>&& lhs, SingleLinkedList<Object>&& rhs); template<typename Object> class SingleLinkedList { //in order to refer to a specific instantiation of the template function "Union", "<Object>" is needed friend SingleLinkedList Union<Object>(SingleLinkedList&& lhs, SingleLinkedList&& rhs); //...[main part of class definition ](https://www.cnblogs.com/meixiaogua/p/10175608.html) } //定义Union /*我一开始把返回值定义成&&了,那样是不对的 由于函数Union返回至关因而在执行 SingleLinkedList<Object>&& temp = std::move(u); u告诉咱们本身的资源能够被偷走,而后把资源位置写到temp变量中,而后u的资源就被函数销毁了。 就至关于temp里面记录的资源位置还没来得及被人注意到,那个资源就失效了 正确的方法是定义返回值类型为SingleLinkedList<Object>*/ template<typename Object> SingleLinkedList<Object> Union(SingleLinkedList<Object>&& lhs, SingleLinkedList<Object>&& rhs) { SingleLinkedList<Object> u(std::move(lhs)); if(!rhs.empty()) { u.sentinelPrev->next = rhs.sentinel->next; rhs.sentinelPrev->next = u.sentinel; u.sentinelPrev = rhs.sentinelPrev; rhs.sentinel->next = rhs.sentinelPrev = rhs.sentinel; } return std::move(u); } void testUnion() { using namespace std; SingleLinkedList<int> a,b; for(int i = 0; i != 4; ++i) a.push_back(i); for(int i = 10; i != 14; ++i) b.push_back(i); auto r = Union(std::move(a),std::move(b)); decltype(a) u(std::move(r)); while(!u.empty()) { cout << u.front() << " "; u.pop_front(); } cout << endl; } //测试输出 0 1 2 3 10 11 12 13