• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-159  評論-223  文章-30  trackbacks-0
               在《基于雙端堆實現(xiàn)的優(yōu)先級隊列(1):原理》一文中講述了雙端堆的相關(guān)原理,本文則詳細講述具體的內(nèi)部實現(xiàn),便于區(qū)分,內(nèi)部函數(shù)名稱都以雙下劃線作為前綴,在這里,有幾個關(guān)鍵問題需要說明
               1)怎么求一個結(jié)點的對稱結(jié)點:如果完全二叉樹根結(jié)點從索引1開始但不存儲元素,那么最小堆根結(jié)點則在索引2,最大堆根結(jié)點則在索引3,4和5為2的左右孩子,6和7為3的左右孩子,依次排下來,可以發(fā)現(xiàn)2(00000010)^1(00000001)=3(000000011),3(00000011)^1(00000001)=2,4(00000100)^2(00000010)=6(00000110),6(00000110)^2(00000010)=4(00000100),......因此,使用異或運算就可求得對稱結(jié)點,問題的關(guān)鍵變?yōu)槿绾吻蟮昧硪徊僮鲾?shù)如 和2,3異或的1,和4,6異或的2,這個1,2正是2(3),4(6)的以2為底的整數(shù)對數(shù)(向下取整)值,而這個值可以使用位運算來高效地完成。這里的索引有效范圍是非負數(shù)。
               2)怎么判斷結(jié)點在最小堆或最大堆內(nèi):由1)分析,顯而易見可得,2(00000010)&1(00000001)=0,3(00000011)&1(00000001)=1,4(00000100)&2(00000010)=0,6(00000110)&2(00000010)=2,......因此,可以使用與運算來高效地判斷。
               3)為了充分利用空間,我的實現(xiàn)是最小堆根結(jié)點在索引0,最大堆根結(jié)點在索引1處,那么在這種情況下,解決以上問題1),就需要將結(jié)點索引先加2,再從結(jié)果中減去2;解決以上問題2)需要將結(jié)點索引加2即可。當雙端堆元素數(shù)量占盡全部空間容量時,次最大索引為空間容量減2,加2可能導(dǎo)致整數(shù)溢出,因此在實現(xiàn)中須區(qū)分處理。

               下面是雙端堆操作算法的內(nèi)部函數(shù)實現(xiàn)
              1、 以2為底的整數(shù)對數(shù)(向下取整)
             1struct _64bit_int{};
             2struct _no_64bit_int{};
             3
             4template<typename _Distance>
             5inline _Distance __log2(_Distance _val,_no_64bit_int)
             6{
             7    assert(_val > 0);
             8
             9    _Distance _ret = 0, _tmp;
            10    _tmp = _val >> 16if (_tmp) { _ret += 16; _val = _tmp;}
            11    _tmp = _val >> 8;  if (_tmp) { _ret += 8; _val = _tmp; }
            12    _tmp = _val >> 4;  if (_tmp) { _ret += 4; _val = _tmp; }
            13    _tmp = _val >> 2;  if (_tmp) { _ret += 2; _val = _tmp; }
            14    _ret += (_val >> 1);
            15
            16    return _ret;
            17}

            18
            19template<typename _Distance>
            20inline _Distance __log2(_Distance _val,_64bit_int)
            21{
            22    assert(_val > 0);
            23
            24    _Distance _ret = 0, _tmp;
            25    _tmp = _val >> 32if (_tmp) { _ret += 32; _val = _tmp;}
            26    _tmp = _val >> 16if (_tmp) { _ret += 16; _val = _tmp;}
            27    _tmp = _val >> 8;  if (_tmp) { _ret += 8; _val = _tmp; }
            28    _tmp = _val >> 4;  if (_tmp) { _ret += 4; _val = _tmp; }
            29    _tmp = _val >> 2;  if (_tmp) { _ret += 2; _val = _tmp; }
            30    _ret += (_val >> 1);
            31
            32    return _ret;
            33}

            34
            35template<typename _Distance>
            36inline _Distance __log2(_Distance val)
            37{
            38    return __log2(val,typename cppext::mpl::if_then_else<8==sizeof(_Distance),_64bit_int,_no_64bit_int>::type());
            39}
               2、對稱結(jié)點計算和判斷函數(shù)
             1template<typename _Distance>
             2inline bool __is_max_dheap_until(_Distance _dist) 
             3{
             4    assert(_dist > 1);
             5    return 0!=(_dist&(((_Distance)1)<<(__log2(_dist)-1)));
             6}

             7
             8template<typename _Distance>
             9inline bool __is_max_dheap(_Distance _dist) 
            10{
            11    _Distance _tmp = _dist + 2;
            12    return _tmp > _dist ?  __is_max_dheap_until(_tmp) : __is_max_dheap_until((_dist>>1- 1);
            13}

            14
            15template<typename _Distance>
            16inline _Distance __partner_dheap_until(_Distance _dist)
            17{
            18    assert(_dist > 1);
            19    return _dist^(((_Distance)1)<<(__log2(_dist)-1));
            20}

            21
            22template<typename _Distance>
            23inline _Distance __partner_dheap(_Distance _dist)
            24{
            25    _Distance _tmp = _dist + 2;
            26    return _tmp > _dist ?  __partner_dheap_until(_tmp) - 2 : __partner_dheap_until((_dist>>1- 1- 2;
            27}
               3、最大堆最小堆的插入
             1template<typename _RandIt,typename _Distance,typename _Ty>
             2inline void __push_min_dheap(_RandIt _first,_Distance _hole,_Distance _top,_Ty _val,bool _flag = true)
             3{
             4    for (_Distance _parent;_hole > _top;)
             5    {
             6        _parent = (_hole - 2>> 1;
             7        if (!_flag && _parent == _top || *(_first + _parent) < _val) 
             8            break;
             9        *(_first + _hole) = *(_first + _parent);
            10        _hole = _parent;
            11    }

            12    *(_first + _hole) = _val;
            13}

            14
            15template<typename _RandIt,typename _Distance,typename _Ty,typename _Compare>
            16inline void __push_min_dheap(_RandIt _first,_Distance _hole,_Distance _top,_Ty _val,_Compare _comp,bool _flag = true)
            17{
            18    for (_Distance _parent;_hole > _top;)
            19    {
            20        _parent = (_hole - 2>> 1;
            21        if (!_flag && _parent == _top || _comp(*(_first + _parent),_val))
            22            break;
            23        *(_first + _hole) = *(_first + _parent);
            24        _hole = _parent;
            25    }

            26    *(_first + _hole) = _val;
            27}

            28
            29template<typename _RandIt,typename _Distance,typename _Ty>
            30inline void __push_max_dheap(_RandIt _first,_Distance _hole,_Distance _top,_Ty _val,bool _flag = true)
            31{
            32    for (_Distance _parent;_hole > _top;)
            33    {
            34        _parent = (_hole - 2>> 1;
            35        if (!_flag && _parent == _top || _val < *(_first + _parent))
            36            break;
            37        *(_first + _hole) = *(_first + _parent);
            38        _hole = _parent;
            39    }

            40    *(_first + _hole) = _val;
            41}

            42
            43template<typename _RandIt,typename _Distance,typename _Ty,typename _Compare>
            44inline void __push_max_dheap(_RandIt _first,_Distance _hole,_Distance _top,_Ty _val,_Compare _comp,bool _flag = true)
            45{
            46    for (_Distance _parent;_hole > _top;)
            47    {
            48        _parent = (_hole - 2>> 1;
            49        if (!_flag && _parent == _top || _comp(_val,*(_first + _parent)))
            50            break;
            51        *(_first + _hole) = *(_first + _parent);
            52        _hole = _parent;
            53    }

            54    *(_first + _hole) = _val;
            55}
               4、最大堆調(diào)整
              1template<typename _RandIt,typename _Distance,typename _Ty>
              2inline void __adjust_max_dheap(_RandIt _first,_Distance _len,_Distance _hole,_Ty _val,bool _flag = true)
              3{
              4    assert(_len > 0);
              5
              6    _Distance _parent,_child,_tmp,_part,_min,_max,_bottom = _len - 1, _half = _bottom >> 1;
              7    for(_parent = _hole;_parent < _half;)
              8    {
              9        _child = (_parent + 1<< 1;
             10        if (_child < _bottom)
             11        {
             12            _tmp = _child;
             13            if (++_tmp <= _bottom && *(_first + _child) < *(_first + _tmp))
             14                ++_child;
             15        }

             16        *(_first + _parent) = *(_first + _child);
             17        _parent = _child;
             18    }

             19
             20    _part = __partner_dheap(_parent),_tmp = (_part + 1<< 1;
             21    if(_tmp != _bottom)
             22    {
             23        if (_tmp < _bottom)
             24            _part = _tmp, ++_tmp ;
             25        else
             26            (_part&1)==0 ? _tmp = _part + 1 : _tmp = _part - 1;
             27
             28        if (*(_first + _part) < *(_first + _tmp))
             29            _min = _part,_max = _tmp;
             30        else 
             31            _min = _tmp,_max = _part;
             32    }

             33    else
             34    {
             35        _min = _max = _tmp;
             36    }

             37
             38    if (*(_first + _min) < _val)
             39    {
             40        if (_val < *(_first + _max))
             41        {
             42            if (*(_first + _parent) < *(_first + _max))
             43                *(_first + ((_parent - 2>> 1)) = *(_first + _max);    
             44            else
             45                *(_first + _parent) = *(_first + _max);
             46            *(_first + _max) = _val; 
             47        }

             48        else
             49        {
             50            __push_max_dheap(_first,_parent,_hole,_val);
             51        }

             52    }

             53    else
             54    {
             55        if (*(_first + _parent) < *(_first + _max))
             56            *(_first + ((_parent - 2>> 1)) = *(_first + _max);    
             57        else
             58            *(_first + _parent) = *(_first + _max);
             59        *(_first + _max) = *(_first + _min); 
             60        __push_min_dheap(_first,_min,__partner_dheap(_hole),_val,_flag);
             61    }

             62}

             63
             64template<typename _RandIt,typename _Distance,typename _Ty,typename _Compare>
             65inline void __adjust_max_dheap(_RandIt _first,_Distance _len,_Distance _hole,_Ty _val,_Compare _comp,bool _flag = true)
             66{
             67    assert(_len > 0);
             68
             69    _Distance _parent,_child,_tmp,_part,_min,_max,_bottom = _len - 1, _half = _bottom >> 1;
             70    for(_parent = _hole;_parent < _half;)
             71    {
             72        _child = (_parent + 1<< 1;
             73        if (_child < _bottom)
             74        {
             75            _tmp = _child;
             76            if (++_tmp <= _bottom && _comp(*(_first + _child),*(_first + _tmp)))
             77                ++_child;
             78        }

             79        *(_first + _parent) = *(_first + _child);
             80        _parent = _child;
             81    }

             82
             83    _part = __partner_dheap(_parent),_tmp = (_part + 1<< 1;
             84    if(_tmp != _bottom)
             85    {
             86        if (_tmp < _bottom)
             87            _part = _tmp, ++_tmp;
             88        else
             89            (_part&1)==0 ? _tmp = _part + 1 : _tmp = _part - 1;
             90
             91        if (_comp(*(_first + _part),*(_first + _tmp)))
             92            _min = _part,_max = _tmp;
             93        else 
             94            _min = _tmp,_max = _part;
             95    }

             96    else
             97    {
             98        _min = _max = _tmp;
             99    }

            100
            101    if (_comp(*(_first + _min),_val))
            102    {
            103        if (_comp(_val,*(_first + _max)))
            104        {
            105            if (_comp(*(_first + _parent),*(_first + _max)))
            106                *(_first + ((_parent - 2>> 1)) = *(_first + _max);    
            107            else
            108                *(_first + _parent) = *(_first + _max);
            109            *(_first + _max) = _val; 
            110        }

            111        else
            112        {
            113            __push_max_dheap(_first,_parent,_hole,_val,_comp);
            114        }

            115    }

            116    else
            117    {
            118        if (_comp(*(_first + _parent),*(_first + _max)))
            119            *(_first + ((_parent - 2>> 1)) = *(_first + _max);    
            120        else
            121            *(_first + _parent) = *(_first + _max);
            122        *(_first + _max) = *(_first + _min); 
            123        __push_min_dheap(_first,_min,__partner_dheap(_hole),_val,_comp,_flag);
            124    }

            125}
               5、最小堆調(diào)整
             1template<typename _RandIt,typename _Distance,typename _Ty>
             2inline void __adjust_min_dheap(_RandIt _first,_Distance _len,_Distance _hole,_Ty _val)
             3{
             4    assert(_len > 0);
             5
             6    _Distance _parent,_child,_tmp,_part,_bottom = _len - 1, _half = _bottom >> 1;
             7    for(_parent = _hole;_parent < _half;)
             8    {
             9        _child = (_parent + 1<< 1;
            10        if (_child < _bottom)
            11        {
            12            _tmp = _child;
            13            if (++_tmp <= _bottom && *(_first + _tmp) < *(_first + _child))
            14                ++_child;
            15        }

            16        *(_first + _parent) = *(_first + _child);
            17        _parent = _child;
            18    }

            19
            20    _part = __partner_dheap(_parent);
            21    if (_part > 1 && _part > _bottom) _part = (_part - 2>> 1;
            22
            23    if (1 != _part && *(_first + _part) < _val)
            24    {
            25        *(_first + _parent) = *(_first + _part);
            26        __push_max_dheap(_first,_part,__partner_dheap(_hole),_val);
            27    }

            28    else
            29    {
            30        __push_min_dheap(_first,_parent,_hole,_val);
            31    }

            32}

            33
            34template<typename _RandIt,typename _Distance,typename _Ty,typename _Compare>
            35inline void __adjust_min_dheap(_RandIt _first,_Distance _len,_Distance _hole,_Ty _val,_Compare _comp)
            36{
            37    assert(_len > 0);
            38
            39    _Distance _parent,_child,_tmp,_part,_bottom = _len - 1, _half = _bottom >> 1;
            40    for(_parent = _hole;_parent < _half;)
            41    {
            42        _child = (_parent + 1<< 1;
            43        if (_child < _bottom)
            44        {
            45            _tmp = _child;
            46            if (++_tmp <= _bottom && _comp(*(_first + _tmp),*(_first + _child)))
            47                ++_child;
            48        }

            49        *(_first + _parent) = *(_first + _child);
            50        _parent = _child;
            51    }

            52
            53    _part = __partner_dheap(_parent);
            54    if (_part > 1 && _part > _bottom) _part = (_part - 2>> 1;
            55
            56    if (1 != _part && _comp(*(_first + _part),_val))
            57    {
            58        *(_first + _parent) = *(_first + _part);
            59        __push_max_dheap(_first,_part,__partner_dheap(_hole),_val,_comp);
            60    }

            61    else
            62    {
            63        __push_min_dheap(_first,_parent,_hole,_val,_comp);
            64    }

            65}
               7、堆調(diào)整
             1template<typename _RandIt,typename _Distance,typename _Ty>
             2inline void __adjust_dheap(_RandIt _first,_Distance _len,_Distance _hole,_Ty _val,bool _flag = true)
             3{
             4    __is_max_dheap(_hole) ? __adjust_max_dheap(_first,_len,_hole,_val,_flag) : __adjust_min_dheap(_first,_len,_hole,_val);    
             5}

             6
             7template<typename _RandIt,typename _Distance,typename _Ty,typename _Compare>
             8inline void __adjust_dheap(_RandIt _first,_Distance _len,_Distance _hole,_Ty _val,_Compare _comp,bool _flag = true)
             9{
            10    __is_max_dheap(_hole) ? __adjust_max_dheap(_first,_len,_hole,_val,_comp,_flag) : __adjust_min_dheap(_first,_len,_hole,_val,_comp);    
            11}
            posted on 2011-10-03 17:54 春秋十二月 閱讀(2170) 評論(1)  編輯 收藏 引用 所屬分類: Algorithm

            評論:
            # re: 基于雙端堆實現(xiàn)的優(yōu)先級隊列:(3) 外觀 2011-10-04 13:07 | 博洋家紡
            不錯,收藏了  回復(fù)  更多評論
              
            国产精品午夜久久| 久久久免费观成人影院| 国产精品99久久久久久宅男小说| 欧美伊香蕉久久综合类网站| 精品久久无码中文字幕| 成人午夜精品无码区久久| 中文字幕无码久久精品青草| 老司机午夜网站国内精品久久久久久久久 | 国产真实乱对白精彩久久| 久久精品一本到99热免费| 日韩人妻无码精品久久免费一 | 久久亚洲精品无码VA大香大香| 久久久久婷婷| 亚洲一区精品伊人久久伊人| 久久无码国产| 欧美亚洲国产精品久久久久| 97精品伊人久久久大香线蕉| 亚洲AV无码成人网站久久精品大| 嫩草伊人久久精品少妇AV| 国产美女久久久| 精品久久综合1区2区3区激情 | 久久天天躁夜夜躁狠狠躁2022| 久久人人爽人人爽人人av东京热| 久久久久久精品无码人妻| 久久精品人人槡人妻人人玩AV| 久久99精品国产99久久6男男| 亚洲国产精品热久久| 午夜精品久久久久成人| 国内精品伊人久久久久777| 成人国内精品久久久久一区| 国产成人久久精品二区三区| 久久99精品久久久久久9蜜桃| 亚洲欧美久久久久9999| 波多野结衣中文字幕久久| 久久久久国产一区二区| 欧美大香线蕉线伊人久久| 国产精品久久久久久久午夜片| 久久精品综合网| 欧美久久综合性欧美| 亚洲日本va午夜中文字幕久久| 亚洲AV无码久久寂寞少妇|