8. O(1)時間求兩個不相交集合的並集

  • 《算法導論》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
相關文章
相關標籤/搜索