《算法導論》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