blog/assets/js/1e2009d3.7e268ae7.js
2023-09-07 17:53:23 +00:00

1 line
No EOL
25 KiB
JavaScript

"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[3906],{3905:(e,a,t)=>{t.d(a,{Zo:()=>m,kt:()=>u});var n=t(7294);function r(e,a,t){return a in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function l(e,a){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);a&&(n=n.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),t.push.apply(t,n)}return t}function o(e){for(var a=1;a<arguments.length;a++){var t=null!=arguments[a]?arguments[a]:{};a%2?l(Object(t),!0).forEach((function(a){r(e,a,t[a])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):l(Object(t)).forEach((function(a){Object.defineProperty(e,a,Object.getOwnPropertyDescriptor(t,a))}))}return e}function i(e,a){if(null==e)return{};var t,n,r=function(e,a){if(null==e)return{};var t,n,r={},l=Object.keys(e);for(n=0;n<l.length;n++)t=l[n],a.indexOf(t)>=0||(r[t]=e[t]);return r}(e,a);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)t=l[n],a.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=n.createContext({}),p=function(e){var a=n.useContext(s),t=a;return e&&(t="function"==typeof e?e(a):o(o({},a),e)),t},m=function(e){var a=p(e.components);return n.createElement(s.Provider,{value:a},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var a=e.children;return n.createElement(n.Fragment,{},a)}},k=n.forwardRef((function(e,a){var t=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,m=i(e,["components","mdxType","originalType","parentName"]),c=p(t),k=r,u=c["".concat(s,".").concat(k)]||c[k]||d[k]||l;return t?n.createElement(u,o(o({ref:a},m),{},{components:t})):n.createElement(u,o({ref:a},m))}));function u(e,a){var t=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var l=t.length,o=new Array(l);o[0]=k;var i={};for(var s in a)hasOwnProperty.call(a,s)&&(i[s]=a[s]);i.originalType=e,i[c]="string"==typeof e?e:r,o[1]=i;for(var p=2;p<l;p++)o[p]=t[p];return n.createElement.apply(null,o)}return n.createElement.apply(null,t)}k.displayName="MDXCreateElement"},2131:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var n=t(7462),r=(t(7294),t(3905));const l={id:"applications",title:"Pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f",description:"Uk\xe1zka pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f v standardn\xedch kni\u017enic\xedch zn\xe1m\xfdch jazyk\u016f.\n",tags:["balanced trees","red-black trees","applications"],last_update:{date:new Date("2022-04-05T00:00:00.000Z")}},o=void 0,i={unversionedId:"rb-trees/applications",id:"rb-trees/applications",title:"Pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f",description:"Uk\xe1zka pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f v standardn\xedch kni\u017enic\xedch zn\xe1m\xfdch jazyk\u016f.\n",source:"@site/ib002/08-rb-trees/2022-04-05-applications.md",sourceDirName:"08-rb-trees",slug:"/rb-trees/applications",permalink:"/ib002/rb-trees/applications",draft:!1,editUrl:"https://gitlab.com/mfocko/blog/tree/main/ib002/08-rb-trees/2022-04-05-applications.md",tags:[{label:"balanced trees",permalink:"/ib002/tags/balanced-trees"},{label:"red-black trees",permalink:"/ib002/tags/red-black-trees"},{label:"applications",permalink:"/ib002/tags/applications"}],version:"current",lastUpdatedAt:1649116800,formattedLastUpdatedAt:"Apr 5, 2022",frontMatter:{id:"applications",title:"Pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f",description:"Uk\xe1zka pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f v standardn\xedch kni\u017enic\xedch zn\xe1m\xfdch jazyk\u016f.\n",tags:["balanced trees","red-black trees","applications"],last_update:{date:"2022-04-05T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"Red-Black Trees",permalink:"/ib002/category/red-black-trees"},next:{title:"On the rules of the red-black tree",permalink:"/ib002/rb-trees/rules"}},s={},p=[{value:"Pou\u017eit\xed",id:"pou\u017eit\xed",level:2},{value:"R\u016fzn\xe9 implementace",id:"r\u016fzn\xe9-implementace",level:2},{value:"C++",id:"c",level:3},{value:"clang",id:"clang",level:4},{value:"gcc",id:"gcc",level:4},{value:"Java",id:"java",level:3},{value:"C#",id:"c-1",level:3},{value:"Vztah mezi mno\u017einou a mapou",id:"vztah-mezi-mno\u017einou-a-mapou",level:2}],m={toc:p},c="wrapper";function d(e){let{components:a,...t}=e;return(0,r.kt)(c,(0,n.Z)({},m,t,{components:a,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"pou\u017eit\xed"},"Pou\u017eit\xed"),(0,r.kt)("p",null,"\u010cerveno-\u010dern\xe9 stromy jsou celkem obl\xedben\xe9 pro implementaci ADT mno\u017einy nebo slovn\xedku za p\u0159edpokladu, \u017ee nad vkl\xe1dan\xfdmi kl\xed\u010di existuje uspo\u0159\xe1d\xe1n\xed. Jazyky n\xed\u017ee implementuj\xed dan\xe9 datov\xe9 struktury v 2 variant\xe1ch a to:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"se\u0159azen\xe9: pou\u017e\xedvaj\xed na pozad\xed pr\xe1v\u011b \u010derveno-\u010dern\xfd strom"),(0,r.kt)("li",{parentName:"ul"},"nese\u0159azen\xe9: pou\u017e\xedvaj\xed na pozad\xed ha\u0161ovac\xed tabulku")),(0,r.kt)("p",null,"Pro srovn\xe1n\xed, jak jsme si \u0159\xedkali na cvi\u010den\xed, \u010derveno-\u010dern\xfd strom m\xe1 operace hled\xe1n\xed, vkl\xe1d\xe1n\xed a maz\xe1n\xed v \u010dasov\xe9 slo\u017eitosti ",(0,r.kt)("span",{parentName:"p",className:"math math-inline"},(0,r.kt)("span",{parentName:"span",className:"katex"},(0,r.kt)("span",{parentName:"span",className:"katex-mathml"},(0,r.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,r.kt)("semantics",{parentName:"math"},(0,r.kt)("mrow",{parentName:"semantics"},(0,r.kt)("mi",{parentName:"mrow",mathvariant:"script"},"O"),(0,r.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,r.kt)("mi",{parentName:"mrow"},"log"),(0,r.kt)("mo",{parentName:"mrow"},"\u2061"),(0,r.kt)("mi",{parentName:"mrow"},"n"),(0,r.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,r.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\mathcal{O}(\\log n)")))),(0,r.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.kt)("span",{parentName:"span",className:"base"},(0,r.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,r.kt)("span",{parentName:"span",className:"mord mathcal",style:{marginRight:"0.02778em"}},"O"),(0,r.kt)("span",{parentName:"span",className:"mopen"},"("),(0,r.kt)("span",{parentName:"span",className:"mop"},"lo",(0,r.kt)("span",{parentName:"span",style:{marginRight:"0.01389em"}},"g")),(0,r.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,r.kt)("span",{parentName:"span",className:"mord mathnormal"},"n"),(0,r.kt)("span",{parentName:"span",className:"mclose"},")"))))),". Na druhou stranu ha\u0161ovac\xed tabulka m\xe1 ide\xe1ln\u011b konstantn\xed \u010dasovou slo\u017eitost, ale v nejhor\u0161\xedm p\u0159\xedpad\u011b (detaily na posledn\xedm cvi\u010den\xed v semestru) je to bohu\u017eel ",(0,r.kt)("span",{parentName:"p",className:"math math-inline"},(0,r.kt)("span",{parentName:"span",className:"katex"},(0,r.kt)("span",{parentName:"span",className:"katex-mathml"},(0,r.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,r.kt)("semantics",{parentName:"math"},(0,r.kt)("mrow",{parentName:"semantics"},(0,r.kt)("mi",{parentName:"mrow",mathvariant:"script"},"O"),(0,r.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,r.kt)("mi",{parentName:"mrow"},"n"),(0,r.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,r.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\mathcal{O}(n)")))),(0,r.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.kt)("span",{parentName:"span",className:"base"},(0,r.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,r.kt)("span",{parentName:"span",className:"mord mathcal",style:{marginRight:"0.02778em"}},"O"),(0,r.kt)("span",{parentName:"span",className:"mopen"},"("),(0,r.kt)("span",{parentName:"span",className:"mord mathnormal"},"n"),(0,r.kt)("span",{parentName:"span",className:"mclose"},")"))))),"."),(0,r.kt)("p",null,"V\xfd\u0161e jsme si uk\xe1zali n\u011bjak\xe9 p\u0159edpoklady nutn\xe9 pro ha\u0161ovac\xed tabulku i \u010derveno-\u010dern\xfd strom. Co je tedy lep\u0161\xed?"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\u010derveno-\u010dern\xfd strom n\xe1m poskytuje ",(0,r.kt)("em",{parentName:"li"},"stabiln\xed \u010dasovou slo\u017eitost"),", ale za cenu po\u017eadavku ",(0,r.kt)("em",{parentName:"li"},"uspo\u0159\xe1d\xe1n\xed")," nad prvky"),(0,r.kt)("li",{parentName:"ul"},"ha\u0161ovac\xed tabulka n\xe1m poskytuje ",(0,r.kt)("em",{parentName:"li"},"pomyslnou perfektn\xed \u010dasovou slo\u017eitost"))),(0,r.kt)("h2",{id:"r\u016fzn\xe9-implementace"},"R\u016fzn\xe9 implementace"),(0,r.kt)("p",null,"Pro uk\xe1zku pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f v implementac\xedch standardn\xedch knihoven\njsme vybrali n\u011bkolik jazyk\u016f."),(0,r.kt)("p",null,"Pokud V\xe1s zaj\xedmaj\xed r\u016fzn\xe9 implementace, tak bychom doporu\u010dili \u201eprohrab\xe1vat\u201c se p\u0159es n\u011b v n\xe1sleduj\xedc\xedm po\u0159ad\xed: ",(0,r.kt)("inlineCode",{parentName:"p"},"C# \u2192 Java \u2192 C++"),". D\u016fvod pro zvolen\xe9 po\u0159ad\xed vych\xe1z\xed z toho, \u017ee C# implementace je pom\u011brn\u011b \u010diteln\xe1 a obsahuje mno\u017estv\xed vysv\u011btluj\xedc\xedch koment\xe1\u0159\u016f. Implementace v Jav\u011b je stejn\u011b \u010diteln\xe1, a\u010dkoli ji\u017e s minimem koment\xe1\u0159\u016f, kter\xe9 se maxim\xe1ln\u011b odkazuj\xed na CLRS. C++ implementace je \u201ezna\u010dn\u011b pozna\u010den\xe1\u201c podtr\u017e\xedtky ;)"),(0,r.kt)("h3",{id:"c"},"C++"),(0,r.kt)("p",null,"V C++ si m\u016f\u017eeme vybrat mezi 2 r\u016fzn\xfdmi implementacemi (",(0,r.kt)("inlineCode",{parentName:"p"},"clang")," nebo ",(0,r.kt)("inlineCode",{parentName:"p"},"gcc"),")."),(0,r.kt)("h4",{id:"clang"},"clang"),(0,r.kt)("p",null,"Hlavi\u010dkov\xe9 soubory, kter\xe9 pou\u017e\xedv\xe1me p\u0159i pr\xe1ci s mno\u017einou nebo slovn\xedkem (zaj\xedmav\xe9 sekce jsou vyta\u017eeny):"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("a",{parentName:"p",href:"https://github.com/llvm/llvm-project/blob/main/libcxx/include/map"},(0,r.kt)("inlineCode",{parentName:"a"},"map"))),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-cpp"},"template <class _Key, class _Tp, class _Compare = less<_Key>,\n class _Allocator = allocator<pair<const _Key, _Tp> > >\nclass _LIBCPP_TEMPLATE_VIS map\n{\npublic:\n // types:\n typedef _Key key_type;\n typedef _Tp mapped_type;\n typedef pair<const key_type, mapped_type> value_type;\n\n// \u2026\n\nprivate:\n typedef __tree<__value_type, __vc, __allocator_type> __base;\n"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("a",{parentName:"p",href:"https://github.com/llvm/llvm-project/blob/main/libcxx/include/set"},(0,r.kt)("inlineCode",{parentName:"a"},"set"))),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-cpp"},"template <class _Key, class _Compare = less<_Key>,\n class _Allocator = allocator<_Key> >\nclass _LIBCPP_TEMPLATE_VIS set\n{\npublic:\n // types:\n typedef _Key key_type;\n typedef key_type value_type;\n\n// \u2026\n\nprivate:\n typedef __tree<value_type, value_compare, allocator_type> __base;\n")))),(0,r.kt)("p",null,"U obou hlavi\u010dek si m\u016f\u017eeme v\u0161imnout, \u017ee deklaruj\xed n\u011bjak\xfd soukrom\xfd typ ",(0,r.kt)("inlineCode",{parentName:"p"},"__base"),", kter\xfd je aliasem pro ",(0,r.kt)("inlineCode",{parentName:"p"},"__tree"),". Ten n\xe1s pak vede k hlavi\u010dce ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/llvm/llvm-project/blob/main/libcxx/include/__tree"},(0,r.kt)("inlineCode",{parentName:"a"},"__tree")),"."),(0,r.kt)("p",null,"V\xfd\u0148atek:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-cpp"},"/*\n\n_NodePtr algorithms\n\nThe algorithms taking _NodePtr are red black tree algorithms. Those\nalgorithms taking a parameter named __root should assume that __root\npoints to a proper red black tree (unless otherwise specified).\n\n\u2026\n\n*/\n")),(0,r.kt)("h4",{id:"gcc"},"gcc"),(0,r.kt)("p",null,"Pro ",(0,r.kt)("inlineCode",{parentName:"p"},"gcc")," je postup t\xe9m\u011b\u0159 stejn\xfd. Pro zm\u011bnu v hlavi\u010dk\xe1ch ",(0,r.kt)("inlineCode",{parentName:"p"},"map")," a ",(0,r.kt)("inlineCode",{parentName:"p"},"set")," nenajdeme nic, deklarace jsou a\u017e v hlavi\u010dkov\xfdch souborech:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/include/bits/stl_map.h;h=9c2b0745673431b4b396ba27982170478838137e;hb=HEAD"},(0,r.kt)("inlineCode",{parentName:"a"},"bits/stl_map.h"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/include/bits/stl_set.h;h=9c2b0745673431b4b396ba27982170478838137e;hb=HEAD"},(0,r.kt)("inlineCode",{parentName:"a"},"bits/stl_set.h")))),(0,r.kt)("p",null,"V obou se zase odkazuje na n\u011bjakou hlavi\u010dku ",(0,r.kt)("a",{parentName:"p",href:"https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/include/bits/stl_tree.h;h=a4de61417652a288e361a55fcc8bb7a9838c58a5;hb=HEAD"},(0,r.kt)("inlineCode",{parentName:"a"},"bits/stl_tree.h")),", zase v\xfd\u0148atek:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-cpp"}," // Red-black tree class, designed for use in implementing STL\n // associative containers (set, multiset, map, and multimap). The\n // insertion and deletion algorithms are based on those in Cormen,\n // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,\n // 1990), except that\n //\n // (1) the header cell is maintained with links not only to the root\n // but also to the leftmost node of the tree, to enable constant\n // time begin(), and to the rightmost node of the tree, to enable\n // linear time performance when used with the generic set algorithms\n // (set_union, etc.)\n //\n // (2) when a node being deleted has two children its successor node\n // is relinked into its place, rather than copied, so that the only\n // iterators invalidated are those referring to the deleted node.\n\n enum _Rb_tree_color { _S_red = false, _S_black = true };\n\n struct _Rb_tree_node_base\n {\n typedef _Rb_tree_node_base* _Base_ptr;\n typedef const _Rb_tree_node_base* _Const_Base_ptr;\n\n _Rb_tree_color _M_color;\n _Base_ptr _M_parent;\n _Base_ptr _M_left;\n _Base_ptr _M_right;\n\n static _Base_ptr\n _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT\n {\n while (__x->_M_left != 0) __x = __x->_M_left;\n return __x;\n }\n\n static _Const_Base_ptr\n _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT\n {\n while (__x->_M_left != 0) __x = __x->_M_left;\n return __x;\n }\n\n static _Base_ptr\n _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT\n {\n while (__x->_M_right != 0) __x = __x->_M_right;\n return __x;\n }\n\n static _Const_Base_ptr\n _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT\n {\n while (__x->_M_right != 0) __x = __x->_M_right;\n return __x;\n }\n")),(0,r.kt)("p",null,"Tady u\u017e taky vid\xedme n\u011bjak\xfd k\xf3d pro nalezen\xed minima/maxima ve strom\u011b. Mimo jin\xe9\nje\u0161t\u011b existuje ",(0,r.kt)("a",{parentName:"p",href:"https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/src/c%2B%2B98/tree.cc;h=fd14991589a57c6aa847f57105a938cd2bf4df6f;hb=HEAD"},(0,r.kt)("inlineCode",{parentName:"a"},"tree.cc")),", kde je lze nal\xe9zt t\u0159eba funkci s n\xe1sleduj\xedc\xed hlavi\u010dkou:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-cpp"},"void\n_Rb_tree_insert_and_rebalance(const bool __insert_left,\n _Rb_tree_node_base* __x,\n _Rb_tree_node_base* __p,\n _Rb_tree_node_base& __header) throw ();\n")),(0,r.kt)("h3",{id:"java"},"Java"),(0,r.kt)("p",null,"V Jav\u011b jsou pro n\xe1s kl\xed\u010dov\xe9 implementace ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/TreeSet.java"},(0,r.kt)("inlineCode",{parentName:"a"},"TreeSet"))," a ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/TreeMap.java"},(0,r.kt)("inlineCode",{parentName:"a"},"TreeMap")),"."),(0,r.kt)("p",null,"V implementaci ",(0,r.kt)("inlineCode",{parentName:"p"},"TreeSet")," si m\u016f\u017eete pov\u0161imnout:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public class TreeSet<E> extends AbstractSet<E>\n implements NavigableSet<E>, Cloneable, java.io.Serializable\n{\n /**\n * The backing map.\n */\n private transient NavigableMap<E,Object> m;\n\n // Dummy value to associate with an Object in the backing Map\n private static final Object PRESENT = new Object();\n")),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"TreeSet")," v Jav\u011b tedy pou\u017e\xedv\xe1 na pozad\xed ",(0,r.kt)("inlineCode",{parentName:"p"},"TreeMap")," (co\u017e je vid\u011bt ve v\xfdchoz\xedm konstruktoru, kde se vol\xe1 konstruktor p\u0159eb\xedraj\xedc\xed ",(0,r.kt)("inlineCode",{parentName:"p"},"NavigableMap<E, Object>"),", a je mu p\u0159ed\xe1no ",(0,r.kt)("inlineCode",{parentName:"p"},"new TreeMap<>()"),")."),(0,r.kt)("p",null,"Co se t\xfd\u010de ",(0,r.kt)("inlineCode",{parentName:"p"},"TreeMap"),", tak hned ze za\u010d\xe1tku definice ",(0,r.kt)("inlineCode",{parentName:"p"},"TreeMap")," je vid\u011bt:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},'public class TreeMap<K,V>\n extends AbstractMap<K,V>\n implements NavigableMap<K,V>, Cloneable, java.io.Serializable\n{\n /**\n * The comparator used to maintain order in this tree map, or\n * null if it uses the natural ordering of its keys.\n *\n * @serial\n */\n @SuppressWarnings("serial") // Conditionally serializable\n private final Comparator<? super K> comparator;\n\n private transient Entry<K,V> root;\n')),(0,r.kt)("p",null,"Tak\u017ee m\xe1me \u201en\u011bjak\xfd ko\u0159en\u201c typu ",(0,r.kt)("inlineCode",{parentName:"p"},"Entry<K,V>"),". Zkus\xedme si naj\xedt definici dan\xe9ho typu\u2026"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"}," // Red-black mechanics\n\n private static final boolean RED = false;\n private static final boolean BLACK = true;\n\n /**\n * Node in the Tree. Doubles as a means to pass key-value pairs back to\n * user (see Map.Entry).\n */\n\n static final class Entry<K,V> implements Map.Entry<K,V> {\n K key;\n V value;\n Entry<K,V> left;\n Entry<K,V> right;\n Entry<K,V> parent;\n boolean color = BLACK;\n")),(0,r.kt)("p",null,"A m\xe1me RB-tree."),(0,r.kt)("p",null,"(Implementace vych\xe1z\xed z projektu OpenJDK.)"),(0,r.kt)("h3",{id:"c-1"},"C#"),(0,r.kt)("p",null,"V C# se zam\u011b\u0159\xedme na nejnov\u011bj\u0161\xed vyd\xe1n\xed (.NET), kter\xe9 je open-source a podporov\xe1no i na opera\u010dn\xedch syst\xe9mech zalo\u017een\xfdch na Linuxu."),(0,r.kt)("p",null,"Nejd\u0159\xedve se pod\xedv\xe1me na implementaci slovn\xedku (",(0,r.kt)("a",{parentName:"p",href:"https://github.com/dotnet/runtime/blob/main/src/libraries/System.Collections/src/System/Collections/Generic/SortedDictionary.cs"},(0,r.kt)("inlineCode",{parentName:"a"},"SortedDictionary")),")."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-csharp"}," public class SortedDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue> where TKey : notnull\n {\n [NonSerialized]\n private KeyCollection? _keys;\n [NonSerialized]\n private ValueCollection? _values;\n\n private readonly TreeSet<KeyValuePair<TKey, TValue>> _set; // Do not rename (binary serialization)\n")),(0,r.kt)("p",null,"Na prvn\xed pohled m\xe1me probl\xe9m, proto\u017ee ",(0,r.kt)("inlineCode",{parentName:"p"},"TreeSet")," nen\xed ",(0,r.kt)("inlineCode",{parentName:"p"},"SortedSet"),", kter\xfd by jsme \u010dekali. Kdy\u017e se p\u0159esuneme na konec souboru, tak zjist\xedme, \u017ee ",(0,r.kt)("inlineCode",{parentName:"p"},"TreeSet")," je jenom ",(0,r.kt)("em",{parentName:"p"},"backward-compatible wrapper")," pro ",(0,r.kt)("inlineCode",{parentName:"p"},"SortedSet"),"."),(0,r.kt)("p",null,"P\u0159esuneme se k ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/dotnet/runtime/blob/main/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.cs"},(0,r.kt)("inlineCode",{parentName:"a"},"SortedSet")),". A hned ze za\u010d\xe1tku vid\xedme:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-cs"},' // A binary search tree is a red-black tree if it satisfies the following red-black properties:\n // 1. Every node is either red or black\n // 2. Every leaf (nil node) is black\n // 3. If a node is red, the both its children are black\n // 4. Every simple path from a node to a descendant leaf contains the same number of black nodes\n //\n // The basic idea of a red-black tree is to represent 2-3-4 trees as standard BSTs but to add one extra bit of information\n // per node to encode 3-nodes and 4-nodes.\n // 4-nodes will be represented as: B\n // R R\n //\n // 3 -node will be represented as: B or B\n // R B B R\n //\n // For a detailed description of the algorithm, take a look at "Algorithms" by Robert Sedgewick.\n\n internal enum NodeColor : byte\n {\n Black,\n Red\n }\n\n internal delegate bool TreeWalkPredicate<T>(SortedSet<T>.Node node);\n\n internal enum TreeRotation : byte\n {\n Left,\n LeftRight,\n Right,\n RightLeft\n }\n')),(0,r.kt)("p",null,"Vysv\u011btlen\xed v koment\xe1\u0159i trochu p\u0159edb\xedh\xe1 n\xe1pl\u0148 cvi\u010den\xed zam\u011b\u0159en\xe9ho na B-stromy ;)"),(0,r.kt)("h2",{id:"vztah-mezi-mno\u017einou-a-mapou"},"Vztah mezi mno\u017einou a mapou"),(0,r.kt)("p",null,"P\u0159i ka\u017ed\xe9 implementaci ve standardn\xed knihovn\u011b jsme si mohli v\u0161imnout, \u017ee strom implementuje v\u017edy jenom jeden typ:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Jazyk"),(0,r.kt)("th",{parentName:"tr",align:null},"Zp\u016fsob implementace"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"C++"),(0,r.kt)("td",{parentName:"tr",align:null},"mapa ukl\xe1d\xe1 dvojice do mno\u017einy")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Java"),(0,r.kt)("td",{parentName:"tr",align:null},"mno\u017eina ukl\xe1d\xe1 prvky s \u201edummy\u201c hodnotou do mapy")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"C#"),(0,r.kt)("td",{parentName:"tr",align:null},"mapa ukl\xe1d\xe1 dvojice do mno\u017einy")))),(0,r.kt)("p",null,"Mapa vy\u017eaduje, aby ka\u017ed\xfd kl\xed\u010d m\u011bl p\u0159i\u0159azenou pr\xe1v\u011b jednu hodnotu, tedy kl\xed\u010de jsou navz\xe1jem mezi sebou unik\xe1tn\xed. To n\xe1m umo\u017e\u0148uje organizovat kl\xed\u010de do mno\u017einy, zde ale naraz\xedme na nep\u0159\xedjemn\xfd probl\xe9m spo\u010d\xedvaj\xedc\xed v tom, \u017ee mus\xedme do mno\u017einy vkladat dvojice prvk\u016f: ",(0,r.kt)("inlineCode",{parentName:"p"},"(key, value)"),". Tenhle p\u0159\xedstup m\xe1 ale z\xe1sadn\xed probl\xe9m:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-py",metastring:"showLineNumbers",showLineNumbers:!0},"# let's represent dictionary/map as a set\nset_of_values = set()\n\n# let's insert few pairs\nset_of_values.add((1, 2))\nset_of_values.add((0, 42))\n\n# let's set key 1 to value 6\nset_of_values.add((1, 6))\n\nset_of_values\n")),(0,r.kt)("p",null,"A dostaneme:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"{(1, 6), (1, 2), (0, 42)}\n")),(0,r.kt)("p",null,"V jednotliv\xfdch implementac\xedch, kter\xe9 jste mohli vid\u011bt v\xfd\u0161e, se vyu\u017e\xedv\xe1 nasleduj\xedc\xed, kdy\u017e:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("em",{parentName:"li"},"mapa ukl\xe1d\xe1 dvojice do mno\u017einy"),": Dvojice je obalen\xe1 v samostatn\xedm typu, kter\xfd porovn\xe1v\xe1 jenom kl\xed\u010de"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("em",{parentName:"li"},"mno\u017eina ukl\xe1d\xe1 kl\xed\u010de do mapy"),": V map\u011b se ignoruj\xed hodnoty p\u0159i\u0159azen\xe9 kl\xed\u010d\u016fm")))}d.isMDXComponent=!0}}]);