{"id":136,"date":"2021-02-04T23:05:40","date_gmt":"2021-02-04T22:05:40","guid":{"rendered":"https:\/\/tutos.switchelven.fr\/?p=136"},"modified":"2021-02-04T23:05:40","modified_gmt":"2021-02-04T22:05:40","slug":"data-structure-chained-list","status":"publish","type":"post","link":"https:\/\/tutos.switchelven.fr\/fr\/data-structure-chained-list\/","title":{"rendered":"Data structure: Chained List"},"content":{"rendered":"\n<p>Hello World! Here is Switch. Having introduce the bases of programming, it is time to go a bit deeper. This post will start a serie about <strong>data structure<\/strong>. Data structure defines solution to manage data set in a program and using the correct structure will greatly improve code performance. Also, a good structure will simplify the implementation of problem resolution. <\/p>\n\n\n\n<p>As a first post around data structure, I will introduce the basic <strong>Chained List<\/strong> structure. <\/p>\n\n\n\n<p class=\"has-large-font-size\">Structure description<\/p>\n\n\n\n<p>A chain list build upon a single entry point witch represent the Head of the list. The head stores a value and a reference (pointer) to the next listed elements. It has no index notion and is a first in, last out structure. It means that you will neither have a direct access to a known element of the list without depilating all heads before the elements and the first element to be added will be retrieved last.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/tutos.switchelven.fr\/wp-content\/uploads\/2021\/02\/List-graphical-rep-1.png\" alt=\"\" class=\"wp-image-223\" width=\"724\" height=\"113\" srcset=\"https:\/\/tutos.switchelven.fr\/wp-content\/uploads\/2021\/02\/List-graphical-rep-1.png 583w, https:\/\/tutos.switchelven.fr\/wp-content\/uploads\/2021\/02\/List-graphical-rep-1-300x47.png 300w, https:\/\/tutos.switchelven.fr\/wp-content\/uploads\/2021\/02\/List-graphical-rep-1-16x2.png 16w\" sizes=\"auto, (max-width: 724px) 100vw, 724px\" \/><figcaption>Graphical representation of list: [9,1,12]<\/figcaption><\/figure>\n\n\n\n<p>When defining a list, we have to provide user with basic function to manipulate it. We also like to define more advanced powerful tools.<\/p>\n\n\n\n<p>Essentials feature to provide is a <em>Prepend<\/em> method to add element to a list. You also have to provide a <em>Head<\/em> and a <em>Tail<\/em> function to retrieve the first element and queue of current list head.<\/p>\n\n\n\n<p>For advanced tools, I like to provide a <em>Sort<\/em> method witch will allow you to reorder list elements and a <em>Map<\/em> function. The <em>Map<\/em> function allows you to apply a method to each element composing the list. If I call <em>Map<\/em> with a <em>times two <\/em>function on the <em>[9,1,12]<\/em> list, it should return me the <em>[18,2,24]<\/em> list.<\/p>\n\n\n\n<p class=\"has-large-font-size\"> Pseudo code defintion<\/p>\n\n\n\n<p>Now, let&#8217;s propose a pseudo code definition of the list structure. I will introduce a new keywords to our pseudo code: <em>define<\/em> NAME { <em>Properties list <\/em>}. It will create a structure named NAME containing specific values. I can associate methods to this structure using <em>func NAME(Variable).Method<\/em> notation and properties listed in the structure can be accessed through <em>NAME.Property<\/em>. <\/p>\n\n\n\n<p>Let&#8217;s define the basic structure and methods.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">define List {\n  Head any\n  Tail List\n}\n\nemptyList = List{} \/\/ I expect emptyList to be a global constant.\n\nfunc NewList() List {\n   return emptyList\n}\n\nfunc List(l).Prepend(element any) List {\n   return List{\n        Head&lt;-element\n        Tail&lt;-l\n   }\n}\n\nfunc List(l).Pop() any, List {\n    return l.Head, l.Tail\n}<\/code><\/pre>\n\n\n\n<p>Our list structure keeps track of its head and tail by relying on an internal propertie Head and Tail. <em>Head<\/em> is any value you wish to add to the list and <em>Tail<\/em> the reference to next part. I define an <em>emptyList<\/em> constant so we can easily identify it. <em>NewList<\/em> create an empty list where you will be able to add elements. <em>Prepend<\/em> method takes the value you provide to it and build a new <em>List<\/em> structure using current <em>List<\/em> element as <em>Tail<\/em>. Finally, the <em>Pop<\/em> method will return you a couple containing the <em>Head<\/em> value of the list and the full <em>Tail<\/em> list.<\/p>\n\n\n\n<p>Then let&#8217;s simply sort the list. I will propose the basic <em>bubble sort<\/em> implementation. To <em>bubble sort<\/em> a list, you need to sort its tail then add the head at the current place in the sorted list. Witch will give something like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">func List(l).SortedAdd(element any, comp function) List {\n     if l == emptyList {\n         return emptyList\n     }\n\n     if comp(element, l.Head) is True {\n          return List{Head&lt;-element, Tail&lt;-l}\n     }\n\n     return List{Head&lt;-l.Head,Tail&lt;-l.Tail.SortedAdd(element, comp)}\n}\n\nfunc List(l).Sort(comp function) List {\n     if l == emptyList&nbsp;{\n          return l\n     }\n     \n     sorted = l.Tail.Sort()\n     return sorted.Add()\n}<\/code><\/pre>\n\n\n\n<p>Finally, let&#8217;s define the <em>Map<\/em> method. <em>Map<\/em> will go through each <em>Head<\/em> element in <em>List<\/em>, apply provided method and build a new list element using this newly computed value and the application of <em>Map<\/em> to its <em>Tail<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">func List(l).Map(fn function) List {\n     if l == emptyList {\n         return emptyList\n     }\n\n     return List{Head&lt;-fn(l.Head),Tail&lt;-l.Tail.Map(fn)}\n}<\/code><\/pre>\n\n\n\n<p>Now let&#8217;s code it in Go. <\/p>\n\n\n\n<p class=\"has-large-font-size\">Test definition<\/p>\n\n\n\n<p>We will start by defining a code process for our list. We know that we will create a <em>List<\/em> structure witch will contained a <em>Head<\/em> of type <em>interface{}<\/em> (<em>interface <\/em>is a neutral type in Go) and the <em>Tail<\/em> will contained a recursive call to <em>List<\/em> type. For this structure, we wish to define an <em>Empty<\/em> value and an asserter for emptiness. We also wish the constructor of list type to provide an <em>Empty<\/em> list. A first test would then be: <br><em>&#8211; When I create a new list<br>&#8211; I expect it to be an Empty list<\/em><\/p>\n\n\n\n<pre title=\"Constructor test\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\"><em>func TestNewList<\/em>(t *testing.T) {\n   Convey(\"When I create a list\", t, <em>func<\/em>() {\n      newList := list.New()\n      Convey(\"I expect it to be empty\", <em>func<\/em>() {\n         So(newList.Empty(), ShouldBeTrue)\n      })\n   })\n}<\/code><\/pre>\n\n\n\n<p>Then we would like to add element to a list. After adding an element, I should ensure the updated list is not empty, as a <em>Head<\/em> value equal to provided data, and has a tail equals to initial list. The test protocol would be:<br><em>&#8211; Given I have an empty list<br>&#8211; When I add an element X<br>&#8211; List should not be Empty<br>&#8211; Head should equal X<br>&#8211; Tail should be empty<\/em><br><br><em>&#8211; Given I have a list L <br>&#8211; When I add an element X stored as newL<br>&#8211; newL should not be Empty<br>&#8211; newL Head should equal X<br>&#8211; newL Tail should equal L<\/em><\/p>\n\n\n\n<pre title=\"Prepend test\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">Convey(\"Given I have \", t, <em>func<\/em>() {\n   Convey(\"an Empty list\", <em>func<\/em>() {\n      l := list.New()\n      Convey(\"When I add an element X\", <em>func<\/em>() {\n         newL := l.Prepend(\"X\")\n\n         So(newL.Empty(), ShouldBeFalse)\n         So(newL.Head, ShouldEqual, \"X\")\n         So(newL.Queue.Empty(), ShouldBeTrue)\n      })\n   })\n\n   Convey(\"a list\", <em>func<\/em>() {\n      l := list.New().Prepend(\"X\").Prepend(\"Y\").Prepend(\"Z\")\n      Convey(\"When I add an element X\", <em>func<\/em>() {\n         newL := l.Prepend(\"A\")\n\n         So(newL.Empty(), ShouldBeFalse)\n         So(newL.Head, ShouldEqual, \"A\")\n         So(*newL.Queue, ShouldResemble, l)\n      })\n   })\n})<\/code><\/pre>\n\n\n\n<p>Then we can define test protocol for <em>Pop<\/em>:<br><em>&#8211; Given an Empty list<\/em> <em>L<\/em><br>&#8211; <em>L.Pop() should return nil, EmptyList<\/em><br><br><em>&#8211; Given a [3,4,5] list L<\/em> <br><em>&#8211; L.Pop() should return 3, [4,5] as H, L2<\/em><br><em>&#8211; L2.Pop() should return 4, [5]<\/em><\/p>\n\n\n\n<pre title=\"Pop test\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\">Convey(\"Given\", t, <em>func<\/em>() {\n   Convey(\"an Empty list\", <em>func<\/em>() {\n      l := list.New()\n      h, q := l.Pop()\n      So(h, ShouldBeNil)\n      So(q.Empty(), ShouldBeTrue)\n   })\n\n   Convey(\"a known list\", <em>func<\/em>() {\n      l := list.New().Prepend(5).Prepend(4)\n      l2 := l.Prepend(3)\n      h, q := l2.Pop()\n      So(h, ShouldEqual, 3)\n      So(q, ShouldResemble, l)\n      h2, _ := q.Pop()\n      So(h2, ShouldEqual, 4)\n   })\n})<\/code><\/pre>\n\n\n\n<p>Now, we should ensure <em>Map<\/em> function will behave. <br><em>&#8211; Given an Empty List<\/em> <em>L<\/em><br><em>&#8211; L.Map(func(e interface{}) {return e}) should return Empty List<\/em><br><br><em>&#8211; Given a single element list L = [&#8220;hello&#8221;]<\/em><br><em>&#8211; And a function addWorld witch add &#8221; world!&#8221; to string interface<\/em><br><em>&#8211; When I call L.Map(addWorld)<\/em><br><em>&#8211; Then I should have [&#8220;hello world!&#8221;] list<\/em><br><br><em>&#8211; Given a  list L = [&#8220;hello&#8221;, &#8220;my&#8221;, &#8220;new&#8221;]<\/em><br><em>&#8211; And a function addWorld witch add &#8221; world!&#8221; to string interface<\/em><br><em>&#8211; When I call L.Map(addWorld)<\/em><br><em>&#8211; Then I should have [&#8220;hello world!&#8221;, &#8220;my world!&#8221;, &#8220;new world!&#8221;] list<\/em><\/p>\n\n\n\n<pre title=\"Map test\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\"><em>func TestList_Map<\/em>(t *testing.T) {\n   Convey(\"Given \", t, <em>func<\/em>() {\n      Convey(\"an Empty list\", <em>func<\/em>() {\n         l := list.New()\n         Convey(\"when I apply Map function\", <em>func<\/em>() {\n            newL := l.Map(<em>func<\/em>(e <em>interface<\/em>{}) <em>interface<\/em>{} { <em>return <\/em>e })\n            So(newL.Empty(), ShouldBeTrue)\n         })\n      })\n\n      l := list.New()\n      addWorld := <em>func<\/em>(e <em>interface<\/em>{}) <em>interface<\/em>{} { <em>return <\/em>e.(string) + \" world!\" }\n\n      Convey(\"a single element list\", <em>func<\/em>() {\n         l = l.Prepend(\"hello\")\n         expectedL := list.New().Prepend(\"hello world!\")\n         Convey(\"when I apply Map function\", <em>func<\/em>() {\n            newL := l.Map(addWorld)\n            So(*newL, ShouldResemble, expectedL)\n         })\n      })\n      Convey(\"a  list\", <em>func<\/em>() {\n         l = l.Prepend(\"new\").Prepend(\"my\").Prepend(\"hello\")\n         expectedL := list.New().Prepend(\"new world!\").Prepend(\"my world!\").Prepend(\"hello world!\")\n         Convey(\"when I apply Map function\", <em>func<\/em>() {\n            newL := l.Map(addWorld)\n            So(*newL, ShouldResemble, expectedL)\n         })\n      })\n   })\n}<\/code><\/pre>\n\n\n\n<p>Finally, we should safe the sort function. Again, sort function should not alter empty or single element list. Also, given a sorted list, the list should stay sorted and given a randomly ordered list.<br><\/p>\n\n\n\n<pre title=\"Sort test\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\"><em>func TestList_BullSort<\/em>(t *testing.T) {\n   Convey(\"Given a list\", t, <em>func<\/em>() {\n      tmpList := list.New().Prepend(1).Prepend(4).Prepend(6).Prepend(9).Prepend(3).Prepend(5).Prepend(2).Prepend(10)\n\n      expectedSorted := list.New().\n         Prepend(1).Prepend(2).Prepend(3).Prepend(4).Prepend(5).\n         Prepend(6).Prepend(9).Prepend(10)\n\n      l := &amp;tmpList\n      comp := <em>func<\/em>(a, b <em>interface<\/em>{}) bool {\n         <em>return <\/em>a.(int) &gt; b.(int)\n      }\n\n      Convey(\"empty or single element, should stay as his\", func() {\n      })\n\n      Convey(\"not sorted, I should be able to sort it\", <em>func<\/em>() {\n<em>func TestList_BullSort<\/em>(t *testing.T) {\n   Convey(\"Given a list\", t, <em>func<\/em>() {\n      tmpList := list.New().Prepend(1).Prepend(4).Prepend(6).Prepend(9).Prepend(3).Prepend(5).Prepend(2).Prepend(10)\n\n      expectedSorted := list.New().\n         Prepend(1).Prepend(2).Prepend(3).Prepend(4).Prepend(5).\n         Prepend(6).Prepend(9).Prepend(10)\n\n      l := &amp;tmpList\n      comp := <em>func<\/em>(a, b <em>interface<\/em>{}) bool {\n         <em>return <\/em>a.(int) &gt; b.(int)\n      }\n\n      Convey(\"empty or single element, should stay as his\", <em>func<\/em>() {\n         l := list.New()\n         So(l.BullSort(comp), ShouldResemble, &amp;l)\n\n         l = list.New().Prepend(1)\n         So(l.BullSort(comp), ShouldResemble, &amp;l)\n      })\n\n      Convey(\"not sorted, I should be able to sort it\", <em>func<\/em>() {\n         l = l.BullSort(comp)\n         So(*l, ShouldResemble, expectedSorted)\n      })\n\n      Convey(\"sorted, I should be able to sort it\", <em>func<\/em>() {\n         l = l.BullSort(comp)\n         l = l.BullSort(comp)\n         So(*l, ShouldResemble, expectedSorted)\n      })\n   })\n}<\/code><\/pre>\n\n\n\n<p>Then, we just have to complete our code until test pass.<\/p>\n\n\n\n<p class=\"has-large-font-size\">Implementation<\/p>\n\n\n\n<pre title=\"List implementation\" class=\"wp-block-code\"><code lang=\"go\" class=\"language-go\"><em>package <\/em>list\n\n<em>\/\/ List represents a simple chained list.\n\/\/ Head provides the element\ntype <\/em>List <em>struct <\/em>{\n   Head <em>interface<\/em>{}\n   Tail *List\n}\n\n<em>\/\/ MapFunc abstracts Map method arguments type\ntype <\/em>MapFunc <em>func<\/em>(element <em>interface<\/em>{}) <em>interface<\/em>{}\n\n<em>\/\/ New initialize an empty list\nfunc New<\/em>() List {\n   <em>return <\/em>List{Tail: nil, Head: nil}\n}\n\n<em>\/\/ Empty asserts list is an empty list.\nfunc <\/em>(l List) <em>Empty<\/em>() bool {\n   <em>return <\/em>l.Head == nil &amp;&amp; l.Tail == nil\n}\n\n<em>\/\/ Prepend adds elements to list head.\nfunc <\/em>(l List) <em>Prepend<\/em>(elem <em>interface<\/em>{}) List {\n   <em>return <\/em>List{\n      Head: elem,\n      Tail: &amp;l,\n   }\n}\n\n<em>\/\/ Pop recovers head and queue\nfunc <\/em>(l List) <em>Pop<\/em>() (head <em>interface<\/em>{}, queue List) {\n   <em>if <\/em>l.Empty() {\n      <em>return <\/em>nil, l\n   }\n   <em>return <\/em>l.Head, *l.Tail\n}\n\n<em>\/\/ Map applies a function to each element of a list\nfunc <\/em>(l *List) <em>Map<\/em>(fn MapFunc) *List {\n   <em>if <\/em>l.Empty() {\n      <em>return <\/em>l\n   }\n\n   <em>return <\/em>&amp;List{\n      Head: fn(l.Head),\n      Tail: l.Tail.Map(fn),\n   }\n}\n\n<em>\/\/ AddSorted adds an element to sorted list at the right place.\n\/\/ \/!\\ function will not work correctly on non sorted list.\nfunc <\/em>(l *List) <em>AddSorted<\/em>(e <em>interface<\/em>{}, comp <em>func<\/em>(<em>interface<\/em>{}, <em>interface<\/em>{}) bool) *List {\n   <em>if <\/em>l.Empty() {\n      <em>return <\/em>&amp;List{Head: e, Tail: l}\n   }\n\n   <em>if <\/em>comp(e, l.Head) {\n      <em>return <\/em>&amp;List{Head: e, Tail: l}\n   }\n\n   <em>return <\/em>&amp;List{Head: l.Head, Tail: l.Tail.AddSorted(e, comp)}\n}\n\n<em>\/\/ BullSort sorts a list\nfunc <\/em>(l *List) <em>BullSort<\/em>(comp <em>func<\/em>(<em>interface<\/em>{}, <em>interface<\/em>{}) bool) *List {\n   <em>if <\/em>l.Empty() {\n      <em>return <\/em>l\n   }\n\n   sorted := l.Tail.BullSort(comp)\n\n   <em>return <\/em>sorted.AddSorted(l.Head, comp)\n}<\/code><\/pre>\n\n\n\n<p>You will find all code written in this article on github: <a href=\"https:\/\/github.com\/switchelven\/data-structure\">https:\/\/github.com\/switchelven\/data-structure<\/a><\/p>\n\n\n\n<p>That&#8217;s all folks. See you later.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Presentation and implementation of List data structure<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,5],"tags":[17,15,18],"class_list":["post-136","post","type-post","status-publish","format-standard","hentry","category-theorie","category-tutorial","tag-data-structure","tag-go","tag-liste","entry"],"_links":{"self":[{"href":"https:\/\/tutos.switchelven.fr\/fr\/wp-json\/wp\/v2\/posts\/136","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tutos.switchelven.fr\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tutos.switchelven.fr\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tutos.switchelven.fr\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tutos.switchelven.fr\/fr\/wp-json\/wp\/v2\/comments?post=136"}],"version-history":[{"count":9,"href":"https:\/\/tutos.switchelven.fr\/fr\/wp-json\/wp\/v2\/posts\/136\/revisions"}],"predecessor-version":[{"id":232,"href":"https:\/\/tutos.switchelven.fr\/fr\/wp-json\/wp\/v2\/posts\/136\/revisions\/232"}],"wp:attachment":[{"href":"https:\/\/tutos.switchelven.fr\/fr\/wp-json\/wp\/v2\/media?parent=136"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tutos.switchelven.fr\/fr\/wp-json\/wp\/v2\/categories?post=136"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tutos.switchelven.fr\/fr\/wp-json\/wp\/v2\/tags?post=136"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}