{"id":3638,"date":"2019-07-14T01:55:15","date_gmt":"2019-07-13T17:55:15","guid":{"rendered":"https:\/\/damogame.cn\/wordpress\/?p=3638"},"modified":"2019-07-17T23:25:48","modified_gmt":"2019-07-17T15:25:48","slug":"%e6%9c%ac%e4%ba%ba%e5%ae%9e%e7%8e%b0%e7%9a%84%e8%b7%b3%e8%b7%83%e8%a1%a8","status":"publish","type":"post","link":"https:\/\/i007.cc\/wordpress\/archives\/3638","title":{"rendered":"\u672c\u4eba\u5b9e\u73b0\u7684\u8df3\u8dc3\u8868"},"content":{"rendered":"<p>\u81ea\u5df1\u5b9e\u73b0\u4e86\u4e00\u4e2a\u8df3\u8dc3\u8868\uff0c\u4e00\u5171\u4e09\u4e2a\u6587\u4ef6\uff0c\u4f7f\u7528\u7684\u662fc++\uff0c\u505a\u6210\u4e86\u6a21\u677f<\/p>\n<p>\u5f53\u7136\u53c2\u8003\u8fc7\u522b\u4eba\u7684\u4f5c\u54c1\u3002<\/p>\n<p>skipnode.h<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">#ifndef SKIP_LIST_NODE_H_\r\n#define SKIP_LIST_NODE_H_\r\n\r\nnamespace skiplist {\r\n    template&lt;typename SortField, typename Value&gt;\r\n    class Node;\r\n\r\n    template&lt;typename SortField, typename Value&gt;\r\n    struct Level {\r\n        Level() : forward(nullptr), span(0) {};\r\n\r\n        Node&lt;SortField, Value&gt;* forward;\r\n        int span;\t\/\/\u8de8\u5ea6\r\n    };\r\n\r\n    template&lt;typename SortField, typename Value&gt;\r\n    class Node {\r\n    public:\r\n        Node(int node_level, const SortField&amp; sort_field, const Value&amp; value) \r\n            : node_level_(node_level), sort_field_(sort_field), value_(value) {\r\n            if (node_level_ &gt; 0) {\r\n                level_ = new Level&lt;SortField, Value&gt;[node_level_];\r\n            }\r\n            else {\r\n                level_ = nullptr;\r\n            }\r\n        };\r\n\r\n        ~Node() {\r\n            if (level_ != nullptr)\r\n                delete[] level_;\r\n        };\r\n\r\n        const Node&lt;SortField, Value&gt;* next() const {\r\n            return level_[0].forward;\r\n        };\r\n\r\n    public:\r\n        const SortField sort_field_;\r\n        const Value value_;\r\n        const int node_level_; \/\/\u4ece1\u5f00\u59cb\r\n        Level&lt;SortField, Value&gt;* level_;\r\n    };\r\n}\r\n\r\n#endif \/\/SKIP_LIST_NODE_H_\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>random.h<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">#ifndef SKIP_LIST_RANDOM_H_\r\n#define SKIP_LIST_RANDOM_H_\r\n#include &lt;random&gt;\r\n\r\nnamespace skiplist {\r\n    class Random {\r\n    public:\r\n        template &lt;class T&gt;\r\n        static T RandomInt(T low, T high) {\r\n            static std::random_device rd;\r\n            static std::default_random_engine engine(rd());\r\n\r\n            std::uniform_int_distribution&lt;T&gt; dis(0, high - low);\r\n            T dice_roll = dis(engine) + low;\r\n            return dice_roll;\r\n        }\r\n    };\r\n}\r\n\r\n#endif \/\/SKIP_LIST_RANDOM_H_\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>skiplist.h<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">#ifndef SKIP_LIST_H_\r\n#define SKIP_LIST_H_\r\n\r\n#include &lt;iostream&gt;\r\n#include \"skipnode.h\"\r\n#include \"random.h\"\r\n\r\nnamespace skiplist {\r\n    template&lt;typename SortField, typename Value&gt;\r\n    class SkipList {\r\n    public:\r\n        SkipList() : max_level_(0), node_count_(0) {\r\n            header_ = new Node&lt;SortField, Value&gt;(MAX_LEVEL, SortField(), Value());\r\n            footer_ = new Node&lt;SortField, Value&gt;(0, SortField(), Value());\r\n            for (int i = 0; i &lt; MAX_LEVEL; i++) {\r\n                header_-&gt;level_[i].forward = footer_;\r\n            }\r\n        };\r\n\r\n        ~SkipList() { \r\n            clear();\r\n            delete header_;\r\n            delete footer_;\r\n        };\r\n\r\n        const Node&lt;SortField, Value&gt;* find(const SortField&amp; sort_field, int* rank = nullptr) const;\r\n        const Node&lt;SortField, Value&gt;* at(int rank) const;\r\n        const Node&lt;SortField, Value&gt;* back() const;\r\n        bool insert(const SortField&amp; sort_field, const Value&amp; value);\r\n        bool remove(const SortField&amp; sort_field);\r\n\r\n        int max_level() const { return max_level_; };\r\n        int size() const { return node_count_; };\r\n\r\n        \/\/\u6e05\u7a7a\u8df3\u8dc3\u8868\uff0c\u6ce8\u610f\u5934\u8282\u70b9\u548c\u5c3e\u8282\u70b9\u4f1a\u4fdd\u7559\r\n        void clear() {\r\n            Node&lt;SortField, Value&gt;* p = header_-&gt;level_[0].forward;\r\n            while (p != footer_) {\r\n                Node&lt;SortField, Value&gt;* q = p-&gt;level_[0].forward;\r\n                delete p;\r\n                p = q;\r\n            }\r\n            for (int i = 0; i &lt; MAX_LEVEL; i++) {\r\n                header_-&gt;level_[i].forward = footer_;\r\n                header_-&gt;level_[i].span = 0;\r\n            }\r\n            node_count_ = 0;\r\n            max_level_ = 0;\r\n        }\r\n        const Node&lt;SortField, Value&gt;* begin() const { return header_-&gt;level_[0].forward; }\r\n        const Node&lt;SortField, Value&gt;* end() const { return footer_; }\r\n\r\n        void DumpAllNodes() const;\r\n        void DumpNodeDetail(const Node&lt;SortField, Value&gt;* node) const;\r\n\r\n    private:\r\n        Node&lt;SortField, Value&gt;* CreateNode(const SortField&amp; sort_field, const Value&amp; value) const {\r\n            int nodeLevel = GetRandomLevel();\r\n            if (node_count_ == 0) {\r\n                nodeLevel = 1;\r\n            } else if (nodeLevel &gt; max_level_) {\r\n                nodeLevel = max_level_ + 1;\r\n            }\r\n\r\n            Node&lt;SortField, Value&gt;* node = new Node&lt;SortField, Value&gt;(nodeLevel, sort_field, value);\r\n            return node;\r\n        }\r\n\r\n        \/\/\u968f\u673a\u751f\u6210\u4e00\u4e2alevel\r\n        static int GetRandomLevel() {\r\n            int level = 1;\r\n            while (level &lt; MAX_LEVEL &amp;&amp; Random::RandomInt(0, 1) == 0) {\r\n                level++;\r\n            }\r\n\r\n            return level;\r\n        }\r\n\r\n    private:\r\n        int max_level_;\t\t\t\t\t\t\/\/\u4ece1\u5f00\u59cb\r\n        int node_count_;\t\t\t\t\t\/\/\u8282\u70b9\u6570\u91cf\uff0c\u4e0d\u5305\u62ec\u5934\u8282\u70b9\u548c\u5c3e\u8282\u70b9\r\n        Node&lt;SortField, Value&gt;* header_;\r\n        Node&lt;SortField, Value&gt;* footer_;\r\n\r\n        static const int MAX_LEVEL = 24;\t\/\/\u6700\u591a\u652f\u63011000\u4e07\u7684\u6570\u636e\u91cf\r\n    };\r\n\r\n    template&lt;typename SortField, typename Value&gt;\r\n    const Node&lt;SortField, Value&gt;* SkipList&lt;SortField, Value&gt;::find(const SortField&amp; sort_field, int* rank) const {\r\n        if (rank != nullptr) {\r\n            *rank = 1;\r\n        }\r\n\r\n        Node&lt;SortField, Value&gt;* node = header_;\r\n        for (int i = max_level_ - 1; i &gt;= 0; --i) {\r\n            \/\/\u627e\u5230\u76ee\u6807\u8282\u70b9\u7684\u524d\u8282\u70b9\r\n            while (node-&gt;level_[i].forward != footer_ &amp;&amp; node-&gt;level_[i].forward-&gt;sort_field_ &lt; sort_field) {\r\n                if (rank != nullptr) *rank += node-&gt;level_[i].span;\r\n                node = node-&gt;level_[i].forward;\r\n            }\r\n        }\r\n\r\n        \/\/\u5982\u679c\u8be5\u8df3\u8dc3\u8868\u4e3a\u7a7a\uff0c\u5934\u8282\u70b9\u5c31\u4f1a\u76f4\u63a5\u6307\u5411\u5c3e\u8282\u70b9\r\n        if (node == footer_)\r\n            return nullptr;\r\n\r\n        node = node-&gt;level_[0].forward;\r\n        if (node == footer_)\r\n            return nullptr;\r\n        if (node-&gt;sort_field_ != sort_field)\r\n            return nullptr;\r\n        return node;\r\n    };\r\n\r\n    \/\/\u83b7\u53d6\u6392\u884c\u699c\u7b2crank\u540d\uff0c\u4ece1\u5f00\u59cb\r\n    template&lt;typename SortField, typename Value&gt;\r\n    const Node&lt;SortField, Value&gt;* SkipList&lt;SortField, Value&gt;::at(int rank) const {\r\n        int cur_rank = 0;\r\n        Node&lt;SortField, Value&gt;* node = header_;\r\n        for (int i = max_level_ - 1; i &gt;= 0; --i) {\r\n            \/\/\u627e\u5230\u76ee\u6807\u8282\u70b9\u7684\u524d\u8282\u70b9\r\n            while (node-&gt;level_[i].forward != footer_ &amp;&amp; cur_rank + node-&gt;level_[i].span &lt; rank) {\r\n                cur_rank += node-&gt;level_[i].span;\r\n                node = node-&gt;level_[i].forward;\r\n            }\r\n        }\r\n\r\n        \/\/\u5982\u679c\u8be5\u8df3\u8dc3\u8868\u4e3a\u7a7a\uff0c\u5934\u8282\u70b9\u5c31\u4f1a\u76f4\u63a5\u6307\u5411\u5c3e\u8282\u70b9\r\n        if (node == footer_)\r\n            return nullptr;\r\n\r\n        cur_rank += node-&gt;level_[0].span;\r\n        node = node-&gt;level_[0].forward;\r\n\r\n        if (node == footer_)\r\n            return nullptr;\r\n        if (cur_rank != rank)\r\n            return nullptr;\r\n        return node;\r\n    }\r\n\r\n    \/\/\u83b7\u53d6\u6700\u540e\u4e00\u4e2a\u8282\u70b9\r\n    template&lt;typename SortField, typename Value&gt;\r\n    const Node&lt;SortField, Value&gt;* SkipList&lt;SortField, Value&gt;::back() const {\r\n        Node&lt;SortField, Value&gt;* node = header_;\r\n        for (int i = max_level_ - 1; i &gt;= 0; --i) {\r\n            while (node-&gt;level_[i].forward != footer_) {\r\n                node = node-&gt;level_[i].forward;\r\n            }\r\n        }\r\n\r\n        \/\/\u5982\u679c\u8be5\u8df3\u8dc3\u8868\u4e3a\u7a7a\uff0c\u5934\u7ed3\u70b9\u5c31\u4f1a\u76f4\u63a5\u6307\u5411\u5c3e\u8282\u70b9\uff0c\u6b64\u65f6\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u4e3a\u7a7a\r\n        if (node == footer_)\r\n            return nullptr;\r\n        return node;\r\n    }\r\n\r\n    template&lt;typename SortField, typename Value&gt;\r\n    bool SkipList&lt;SortField, Value&gt;::insert(const SortField&amp; sort_field, const Value&amp; value) {\r\n        Node&lt;SortField, Value&gt;* update[MAX_LEVEL];\r\n        int rank[MAX_LEVEL];\r\n\r\n        Node&lt;SortField, Value&gt;* node = header_;\r\n        for (int i = max_level_ - 1; i &gt;= 0; --i) {\r\n            \/\/rank[i-1]\u7528\u6765\u8bb0\u5f55\u7b2ci\u5c42\u8fbe\u5230\u63d2\u5165\u4f4d\u7f6e\u7684\u6240\u8de8\u8d8a\u7684\u8282\u70b9\u603b\u6570,\u4e5f\u5c31\u662f\u8be5\u5c42\u6700\u63a5\u8fd1(\u5c0f\u4e8e)\u7ed9\u5b9ascore\u7684\u6392\u540d  \r\n            \/\/rank[i-1]\u521d\u59cb\u5316\u4e3a\u4e0a\u4e00\u5c42\u6240\u8de8\u8d8a\u7684\u8282\u70b9\u603b\u6570,\u56e0\u4e3a\u4e0a\u4e00\u5c42\u5df2\u7ecf\u52a0\u8fc7\r\n            rank[i] = (i == (max_level_ - 1) ? 0 : rank[i+1]);\r\n\r\n            while (node-&gt;level_[i].forward != footer_ &amp;&amp; node-&gt;level_[i].forward-&gt;sort_field_ &lt; sort_field) {\r\n                rank[i] += node-&gt;level_[i].span;\r\n                node = node-&gt;level_[i].forward;\r\n            }\r\n            update[i] = node;\r\n        }\r\n\r\n        node = node-&gt;level_[0].forward;\r\n\r\n        \/\/\u5982\u679ckey\u5df2\u5b58\u5728\r\n        if (node != footer_ &amp;&amp; node-&gt;sort_field_ == sort_field) {\r\n            return false;\r\n        }\r\n\r\n        \/\/\u521b\u5efa\u65b0\u8282\u70b9\r\n        Node&lt;SortField, Value&gt;* newNode = CreateNode(sort_field, value);\r\n\r\n        \/\/\u6bcf\u6b21\u6700\u591a\u589e\u52a0\u4e00\u5c42\r\n        if (newNode-&gt;node_level_ &gt; max_level_) {\r\n            max_level_ = newNode-&gt;node_level_;\r\n            rank[max_level_ - 1] = 0;\r\n            update[max_level_ - 1] = header_;\r\n            update[max_level_ - 1]-&gt;level_[max_level_ - 1].span = size();\r\n        }\r\n\r\n        \/\/\u8c03\u6574forward\u6307\u9488\r\n        for (int i = 0; i &lt; newNode-&gt;node_level_ ; ++i) {\r\n            node = update[i];\r\n            newNode-&gt;level_[i].forward = node-&gt;level_[i].forward;\r\n            node-&gt;level_[i].forward = newNode;\r\n\r\n            newNode-&gt;level_[i].span = node-&gt;level_[i].span - (rank[0] - rank[i]);\r\n            node-&gt;level_[i].span = rank[0] - rank[i] + 1;\r\n        }\r\n\r\n        for (int i = max_level_ - 1; i &gt;= newNode-&gt;node_level_; --i) {\r\n            update[i]-&gt;level_[i].span++;\r\n        }\r\n\r\n        ++node_count_;\r\n        return true;\r\n    };\r\n\r\n    template&lt;typename SortField, typename Value&gt;\r\n    void SkipList&lt;SortField, Value&gt;::DumpAllNodes() const {\r\n        for (const Node&lt;SortField, Value&gt;* itr = begin(); itr != end(); itr = itr-&gt;next()) {\r\n            DumpNodeDetail(itr);\r\n            std::cout &lt;&lt; std::endl;\r\n        }\r\n        std::cout &lt;&lt; std::endl;\r\n    }\r\n\r\n    template&lt;typename SortField, typename Value&gt;\r\n    void SkipList&lt;SortField, Value&gt;::DumpNodeDetail(const Node&lt;SortField, Value&gt;* node) const {\r\n        std::cout &lt;&lt; \"level:\" &lt;&lt; node-&gt;node_level_\r\n            &lt;&lt; \",sort:\" &lt;&lt; node-&gt;sort_field_\r\n            &lt;&lt; \",value:\" &lt;&lt; node-&gt;value_;\r\n        int node_level = node-&gt;node_level_ &gt; max_level_ ? max_level_ : node-&gt;node_level_;\r\n        for (int i = 0; i &lt;= node_level - 1; ++i) {\r\n            std::cout &lt;&lt; \",[forward:\" &lt;&lt; i \r\n                &lt;&lt; \",span:\" &lt;&lt; node-&gt;level_[i].span\r\n                &lt;&lt; \"]-&gt;\" &lt;&lt; node-&gt;level_[i].forward-&gt;sort_field_;\r\n        }\r\n        std::cout &lt;&lt; \" \";\r\n    }\r\n\r\n    template&lt;typename SortField, typename Value&gt;\r\n    bool SkipList&lt;SortField, Value&gt;::remove(const SortField&amp; sort_field) {\r\n        \/\/\u4fdd\u5b58\u7684\u662f\u8981\u5220\u9664\u7684\u524d\u4e00\u4e2a\u8282\u70b9\r\n        Node&lt;SortField, Value&gt;* update[MAX_LEVEL];\r\n        Node&lt;SortField, Value&gt;* node = header_;\r\n        for (int i = max_level_ - 1; i &gt;= 0; --i) {\r\n            while (node-&gt;level_[i].forward != footer_ &amp;&amp; node-&gt;level_[i].forward-&gt;sort_field_ &lt; sort_field) {\r\n                node = node-&gt;level_[i].forward;\r\n            }\r\n            update[i] = node;\r\n        }\r\n\r\n        if (node == footer_)\r\n            return false;\r\n\r\n        node = node-&gt;level_[0].forward;\r\n        if (node == footer_)\r\n            return false;\r\n\r\n        \/\/\u5982\u679c\u8282\u70b9\u4e0d\u5b58\u5728\r\n        if (node-&gt;sort_field_ != sort_field) {\r\n            return false;\r\n        }\r\n\r\n        \/\/\u73b0\u5728node\u5df2\u7ecf\u88ab\u627e\u5230\uff0c\u5c06\u8981\u88ab\u5220\u9664\uff0c\r\n        for (int i = 0; i &lt;= max_level_ - 1; ++i) {\r\n            if (update[i]-&gt;level_[i].forward != node) {\r\n                update[i]-&gt;level_[i].span--;\r\n            } else {\r\n                update[i]-&gt;level_[i].forward = node-&gt;level_[i].forward;\r\n                update[i]-&gt;level_[i].span += (node-&gt;level_[i].span - 1);\r\n            }\r\n        }\r\n        delete node;\r\n\r\n        \/\/\u66f4\u65b0max_level_\u7684\u503c\uff0c\u56e0\u4e3a\u6709\u53ef\u80fd\u5728\u79fb\u9664\u4e00\u4e2a\u8282\u70b9\u4e4b\u540e\uff0cmax_level_\u503c\u4f1a\u53d1\u751f\u53d8\u5316\uff0c\u53ca\u65f6\u964d\u4f4e\u53ef\u63d0\u9ad8\u6027\u80fd\r\n        while (max_level_ &gt; 0 &amp;&amp; header_-&gt;level_[max_level_ - 1].forward == footer_) {\r\n            --max_level_;\r\n        }\r\n\r\n        --node_count_;\r\n        return true;\r\n    };\r\n}\r\n#endif \/\/SKIP_LIST_H_\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u81ea\u5df1\u5b9e\u73b0\u4e86\u4e00\u4e2a\u8df3\u8dc3\u8868\uff0c\u4e00\u5171\u4e09\u4e2a\u6587\u4ef6\uff0c\u4f7f\u7528<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[],"tags":[119],"class_list":["post-3638","post","type-post","status-publish","format-standard","hentry","tag-03-"],"_links":{"self":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts\/3638","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/comments?post=3638"}],"version-history":[{"count":0,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts\/3638\/revisions"}],"wp:attachment":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/media?parent=3638"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/categories?post=3638"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/tags?post=3638"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}