<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: GourineAyoubPrf</title>
    <description>The latest articles on DEV Community by GourineAyoubPrf (@gourineayoubprf).</description>
    <link>https://dev.to/gourineayoubprf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F521416%2F7d686a36-9912-4fff-9767-da626fd105de.png</url>
      <title>DEV Community: GourineAyoubPrf</title>
      <link>https://dev.to/gourineayoubprf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gourineayoubprf"/>
    <language>en</language>
    <item>
      <title>Data Structures and Complexity Part 3: linear Data Structures Stacks and Queues.</title>
      <dc:creator>GourineAyoubPrf</dc:creator>
      <pubDate>Tue, 15 Dec 2020 19:48:06 +0000</pubDate>
      <link>https://dev.to/gourineayoubprf/data-structures-and-complexity-part-3-linear-data-structures-stacks-and-queues-25n7</link>
      <guid>https://dev.to/gourineayoubprf/data-structures-and-complexity-part-3-linear-data-structures-stacks-and-queues-25n7</guid>
      <description>&lt;h3&gt;
  
  
  Stacks :
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Definition :
&lt;/h4&gt;

&lt;p&gt;a stack is a linear data structure that respects the principal of LIFO “Last In First Out” it means that the last element that was entered into the stack will be the first element to get out or the principal of FIFO “Fist In First Out”which means first in first out so the first element entered to the stack will be the first element that gets out, it’s used to model real world problems and it has tow main operations pop() which is used to get the first top element in the stack and push() which is used to add an element at the top of the stack along side with other operation like peek and ifEmpty that will discuss later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why we use stacks ?
&lt;/h3&gt;

&lt;p&gt;Stacks are used to solve many problems since it mimics the behaviour of many real world problems so it’s used as a model of those problems things like :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the undo mechanism in the text editors .&lt;/li&gt;
&lt;li&gt;used in compilers in things like storing the recursive calls and in syntax checking.&lt;/li&gt;
&lt;li&gt;used in DFS (Depth First Search) algorithm in graphs.&lt;/li&gt;
&lt;li&gt;used in so many algorithms because it can model a lot of real world problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to implement a stack ?
&lt;/h3&gt;

&lt;p&gt;Mainly there is two ways to implement a stack either you use arrays or linked lists and in our example we will use linked lists.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;this data structure is already implemented in most of the languages and the implementation sometimes is different from one language to another one , but for the sake of understanding the mechanism of it, we will implement it with it’s operation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EqU39YY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hrglmwtitdfyv98qwb7r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EqU39YY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hrglmwtitdfyv98qwb7r.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Stacks and Complexity :
&lt;/h3&gt;

&lt;p&gt;The following operations push , pop, peek,isFull,isEmpty all has a O(1) time complexity cause they all depends on a simple instructions but if we want to do something like search an element that will take O(n) time complexity since we have to pull every element and put it back in order to loop over all the elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solving a problem using stacks ( balanced brackets problem) :
&lt;/h3&gt;

&lt;p&gt;In this part we will take a problem and try to solve it using the stack and as an example we are taking the famous balanced brackets problem where you need to check if the syntax and the closing of the parenthesis is correct or not in a group of parenthesis ex :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;{()} ==&amp;gt; correct.&lt;/li&gt;
&lt;li&gt;{()]} ==&amp;gt; false.&lt;/li&gt;
&lt;li&gt;{()[] ==&amp;gt; false.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Input : a string containing the parenthesis → Output : true or false.&lt;/p&gt;

&lt;h4&gt;
  
  
  Solution :
&lt;/h4&gt;

&lt;p&gt;In order to solve it using stack what we could do is to add each parenthesis to the stack one by one and each time check if the stack is not empty if the first element in the stack is the right one in example if we are adding the ‘(‘ and the the first element in the stack is ‘)’ then we simply delete the first element from the stack but if not we add the element that we wanted to add and at the end of all the string that we are looping over it’s characters (parenthesis) we check if stack is empty then we return true else we return false that’s indicates that there is a syntax error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kz3OnZr2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1uv2fidaty64j1s1zlth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kz3OnZr2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1uv2fidaty64j1s1zlth.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Queues :
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Definition :
&lt;/h4&gt;

&lt;p&gt;A Queue is a linear data structure that models a real world queue with tow main operations dequeue and enqueue , the queue is similar to the stack but it has tow entry's for the operations one entry for enqueuing elements (from the end) and the other will be for dequeuing elements (from the front) so that the queue will follow the principal of FIFO (First In First Out) in a way that the first added element is the first accessed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why we use Queues ?
&lt;/h3&gt;

&lt;p&gt;Queues can be used to model many real world problems like :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;waiting lines .&lt;/li&gt;
&lt;li&gt;request in web sites to know which client should be served.&lt;/li&gt;
&lt;li&gt;BFS (Breadth First Search) in graphs.&lt;/li&gt;
&lt;li&gt;keep track of the added elements.&lt;/li&gt;
&lt;li&gt;manage shared resources between some entities like CPU processes.&lt;/li&gt;
&lt;li&gt;asynchronous data transfer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to implement a Queue ?
&lt;/h3&gt;

&lt;p&gt;As the stack the queue can be implemented using the arrays or the linked lists data structures , in our implementation we will use linked lists.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;this data structure is already implemented in most of the languages and the implementation sometimes is different from one language to another one , but for the sake of understanding the mechanism of it, we will implement it with it’s operation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O2vqj42D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rpymafbe2jokvfb8lqg3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O2vqj42D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rpymafbe2jokvfb8lqg3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Queues and Complexity :
&lt;/h3&gt;

&lt;p&gt;The basic operations of the queue like enqueue ,dequeue, peek and isEmpty will take O(1) time complexity but operations like contain (search) and remove an element from the middle will take O(n) time complexity since it’s required to dequeue all the element and enqueue then again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solving a Problem using Queues ( BFS algorithm) :
&lt;/h3&gt;

&lt;p&gt;we will try to solve the BFS algorithm with queues (we will talk about tree data structure in the next’s articles).&lt;br&gt;
Considering that we have a tree T we want to search for an element X using the BFS algorithm it means that we will go through the tree elements knowing that we go to through the breadth of each branch first.&lt;/p&gt;

&lt;p&gt;Input : tree T , value X → Output : true / false (or you can return the value if it’s found and -1 else).&lt;/p&gt;

&lt;p&gt;The steps will be the next :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add the root of the tree to the queue and market as a discovered node or a visited node.&lt;/li&gt;
&lt;li&gt;loop over the queue elements and each time do :&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;check if the dequeued element is equal to the value that we are searching for and if true return true .&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;loop over the nodes that are in the same line as the node that we dequeued it means the adjacent nodes and for each node do :&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add the node to the queue and mark it as visited or discovered&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;and at the end if the loop ended without returning a value that means that the value is not found and we must return false.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;in this solution the methods markeNode(),isMarked(), getAdjacentNodes() are methods for the tree structures that are used for : mark a node as visited, check if a node is visited or not, get the adjacent node of some node in a the tree.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HAChodWW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/io959cm0toxjn3p193mb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HAChodWW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/io959cm0toxjn3p193mb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;stacks and Queues are so important in Data structures world and with no doubt they are a must know concepts for all programmers.&lt;/li&gt;
&lt;li&gt;some real world problems require some specific data structures that can model the real world problem into something can be manipulated by the programmer with the best experience in terms of complexity , so you should always seek to know different data structures and concept in order to have many perspectives and different views for the same problems and make your own data structure if it’s the best way.&lt;/li&gt;
&lt;li&gt;understanding the concept of the data structure is the key to know how to use in the best way.&lt;/li&gt;
&lt;li&gt;Hope you had a good reading and learned something from that and stay tuned for the next article about another Data structure.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;this article is also published by me in meduime :&lt;br&gt;
&lt;a href="https://gourineayoub-prf.medium.com/data-structures-and-complexity-part-3-linear-data-structures-stacks-and-queues-5e8e1e72a041"&gt;https://gourineayoub-prf.medium.com/data-structures-and-complexity-part-3-linear-data-structures-stacks-and-queues-5e8e1e72a041&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>computerscience</category>
      <category>beginners</category>
      <category>algorithms</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Data structures and Complexity part2 : linear data part1 (arrays and linked-Lists)</title>
      <dc:creator>GourineAyoubPrf</dc:creator>
      <pubDate>Fri, 11 Dec 2020 20:20:13 +0000</pubDate>
      <link>https://dev.to/gourineayoubprf/data-structures-and-complexity-part2-linear-data-part1-arrays-and-linked-lists-ca8</link>
      <guid>https://dev.to/gourineayoubprf/data-structures-and-complexity-part2-linear-data-part1-arrays-and-linked-lists-ca8</guid>
      <description>&lt;p&gt;Linear data structures is one of the most used DSs in programming it has many different Data structures like arrays linked-lists stack …etc , in this article we will talk about this tow DS arrays and Linked-list ,they are so important and basically every programmer should know about this tow even if he’s is just starting his career he will find arrays and linked lists in the first topic that he will learn due to there importance as a way of storing and manipulating data in a lot of problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arrays (static arrays and dynamic arrays):
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Static arrays :
&lt;/h4&gt;

&lt;p&gt;a static Array is a static data structures that allow you to store any type of data as long as the length of the array is specified at the creation of it, this length can’t be changes since it’s a static DS . Each value in an array has an index that refers to it and gives the programmer a way to access it’s value knowing that the indexes start from 0 to n as an example: the first element of an array of integers will be : integerTable&lt;a href="https://dev.tointegerTable%20is%20the%20name%20of%20the%20table"&gt;0&lt;/a&gt;, the type of data stored in the array in most languages has to be the same type for all values. (ex: all integers or all string , not a few of integers and some other data types).&lt;/p&gt;

&lt;h3&gt;
  
  
  when you should use static arrays ?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;when you know the max length of your array.&lt;/li&gt;
&lt;li&gt;most of the time static arrays are used as temporary memory to store objects.&lt;/li&gt;
&lt;li&gt;used to return multiple values from a function.&lt;/li&gt;
&lt;li&gt;used as buffers for input and output.&lt;/li&gt;
&lt;li&gt;used to store results of the sub solutions like in dynamic programming.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dynamic arrays :
&lt;/h3&gt;

&lt;p&gt;a dynamic array is an array that has no limit to the number of value that you can put in and has the same operation that you can apply to a normal static array.&lt;/p&gt;

&lt;h3&gt;
  
  
  when you should use dynamic arrays ?
&lt;/h3&gt;

&lt;p&gt;basically when you don’t know how much data you need to store.&lt;/p&gt;

&lt;h3&gt;
  
  
  How you can implement a dynamic array ?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D4J_HxSM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/04z4uy1sz0rojgqn8a4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D4J_HxSM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/04z4uy1sz0rojgqn8a4y.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code source for the dynamic array is in this file :&lt;br&gt;
&lt;a href="https://github.com/GourineAyoubPrf/ArrayAndLinkedLists/tree/main/src/arraysandlinkedlistes"&gt;https://github.com/GourineAyoubPrf/ArrayAndLinkedLists/tree/main/src/arraysandlinkedlistes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;one of the ways to make a dynamic arrays is to use static arrays like this :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;at first we have a table of length 1&lt;/li&gt;
&lt;li&gt;each time the user want to add an element to the dynamic array we test the length of the initial array&lt;/li&gt;
&lt;li&gt;if there is place to add : add the element normally in the next index.&lt;/li&gt;
&lt;li&gt;if the size is not enough then:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;create a new array that has a double size of the previous one.&lt;/li&gt;
&lt;li&gt;copy all the element from the previous array to the new .&lt;/li&gt;
&lt;li&gt;add the new element to the new array .&lt;/li&gt;
&lt;li&gt;and finally the new array becomes our initial array and we repeat this process each time when there is no enough space to add.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YtR48tI6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8lbasbxq8w0c3inozx8d.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;in case of the deletion :&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;create a new array with the size of number Of elements in our initial array -1.&lt;/li&gt;
&lt;li&gt;copy all the elements except the element that we want to delete.&lt;/li&gt;
&lt;li&gt;the new array becomes our initial array.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EbXUq3V1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3q0vuwwcfv680i1wbf21.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;this data structures are already implemented in the &amp;gt;programming languages but to understand them more and get &amp;gt;good in working with theme you need to understand how they &amp;gt;are implemented and how they work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the implementation is different from one language to &amp;gt;another some operation are allowed in one language and not &amp;gt;in another but now that you know how things works if &amp;gt;something is not good for you you can implement your own &amp;gt;data structure and make the operations that you want for it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;in java we use this sign  example :  in the &amp;gt;class declaration so we can use the generic types in our &amp;gt;array implementation so it supports all data types. and we &amp;gt;implement the iterator interface in case you want to use &amp;gt;iterator to loop over the elements.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Array Operations :
&lt;/h3&gt;

&lt;p&gt;arrays as a data structures has many operations that can be applied to. We have basic operations like :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search&lt;/li&gt;
&lt;li&gt;add&lt;/li&gt;
&lt;li&gt;access element&lt;/li&gt;
&lt;li&gt;remove element.
and some more complicated and specified operations like :&lt;/li&gt;
&lt;li&gt;remove element at index / remove the first/ remove the last.&lt;/li&gt;
&lt;li&gt;sort the elements.&lt;/li&gt;
&lt;li&gt;invert the table elements&lt;/li&gt;
&lt;li&gt;shift elements&lt;/li&gt;
&lt;li&gt;… etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Array operations complexity :
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JHgYlad2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zlb1uq8rtkde7ct1d1ew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JHgYlad2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zlb1uq8rtkde7ct1d1ew.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The complexity is different from the static array to dynamic array , and also it can be different in one language to another due to the way of implementation but generally this is it :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;we are talking about worst case here because there is some &amp;gt;search methods that can take less time if the array is &amp;gt;ordered (we will talk about searching and sorting methods in &amp;gt;another article).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How arrays are sorted in the memory ?
&lt;/h3&gt;

&lt;p&gt;Arrays are stored in a contiguous space in memory as an example if you have an array of length 10 the compiler will have to find 10 successive places in the memory to store the data (places mean the pace necessary for storing one element of the specified type) , this behavior is only with arrays since it uses indexes so the memory address has to be side to side but it’s different with other DS like linked list (will discus later).&lt;/p&gt;

&lt;h3&gt;
  
  
  Why indexes start from 0 in arrays ?
&lt;/h3&gt;

&lt;p&gt;a little story :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the first creation of arrays in the programming world the address of the array was set to be the address of the first element of that array so they are the same address in the memory , as an example if we have an array of integers named myArray with this values [5,2,6,8,91,100,235] if we say that the address of the first value “5” that we access it like this myArray[0] is the address named 111 (just a a naming ) then the address that reference to the array it self is 111 and when the programmers implemented the arrays (low level implementation) to access an array value they did this operation as example : myArray[5] for the compiler to know it’s place he must do this operation :&lt;/li&gt;
&lt;li&gt;the address of myArray[5] = the address of MyArray + 5 so the address will be 111 + 5 = 116 then he will go to the memory the address 116 an read it value and give it to you as the value of myArray[5] in our case it will be 100. now after you know that imagine that we start from 1 and not 0 and we want to access the value of myArray[1] the compiler have to find the address so 111 + 1 = 112 but the address 112 contains 2 not 5 which is wrong because our first element is 5 and the compiler need each time to do -1 after the sum sow he can get the write result and this will be not good for the performance because we are talking about low level implementation , for that the element’s start from 0 and not from 1.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;to be more clear the address of the element that we try to access is calculated with this formula :&lt;br&gt;
address of accessed element = address of the array + index * &amp;gt;(size of one element of the type that the arrays contain).&lt;br&gt;
Example : if we say an integer take a size of 5 to store one &amp;gt;element then :&lt;br&gt;
address of accessed element = address of the array+ index * &amp;gt;5 (because each integer take a size of 5 in the memory) , &amp;gt;Because each case has a size fit for one element of the &amp;gt;declared type.&lt;br&gt;
If you want to learn more about this you can search about &amp;gt;heap memory and memory management in the operating systems .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Linked list (single linked list, double linked list and circular linked list) :
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Single linked-List (also called just linked-lists):
&lt;/h4&gt;

&lt;p&gt;A linked list is dynamic data structure that let you store any type of data and with no size limits since it’s dynamic , but with a new concept so that each list element or also called node has :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a value with a type specified at the declaration.&lt;/li&gt;
&lt;li&gt;a pointer that point to the address of the next node in the list.&lt;/li&gt;
&lt;li&gt;for the last node his next pointer points to the null value so it’s a special case that indicates that this is the end of the list.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How linked list are stored in memory ?
&lt;/h3&gt;

&lt;p&gt;Not like the arrays that need to allocate a memory at the start of the creation because it has a known size that needed to be allocated , the linked list don’t need to allocate a contiguously space in the memory because each element has a pointer towards the next element of the list so it does not matter where is the place of the next element as long as it has it’s pointer it will always know where to go next until it reaches the null pointer (end of the linked list).&lt;/p&gt;

&lt;h3&gt;
  
  
  Where and Why we need linked-Lists ?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;implementing another data structures like stack queues and graphs.&lt;/li&gt;
&lt;li&gt;used to model real world problems like a trains.&lt;/li&gt;
&lt;li&gt;used as a solution for the hash collision problem in the hash data structures(a problem know in the hash based data structures) .&lt;/li&gt;
&lt;li&gt;one important this is that in arrays if you delete an element that element space still exists but you can do something like put a special character or number (based on the type) in it that it indicates that this element was deleted but the space will be always allocated and can’t be changed unless you delete the whole array but in the linked list as an advantage of the chaining concept with pointer you can delete an element and it’s space in the memory because the memory get allocated and freed each time you add or delete an element.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How can i implement a linked list ?
&lt;/h3&gt;

&lt;p&gt;The code source for the Linked List implementation is in this file :&lt;br&gt;
&lt;a href="https://github.com/GourineAyoubPrf/ArrayAndLinkedLists/tree/main/src/arraysandlinkedlistes"&gt;https://github.com/GourineAyoubPrf/ArrayAndLinkedLists/tree/main/src/arraysandlinkedlistes&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;this data structures are already implemented in most of the &amp;gt;languages . In our example we will use java language as a &amp;gt;tool to implement the linked list you can use any language &amp;gt;you want the concept want change just the syntax. Each &amp;gt;linked list has a pointer of the head and a size property &amp;gt;(you can add other properties if you want)and as we know &amp;gt;each node has a next pointer and a value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9knLg4bX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/edpq2y7codqpf9iw4hqb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9knLg4bX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/edpq2y7codqpf9iw4hqb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Linked-lists operations complexity :
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Add at head :
&lt;/h4&gt;

&lt;p&gt;Since we already have the head pointer so this will take O(1) time complexity because we need just to change the pointer of the head to the new node and link the new node with the previous head.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QhpXyFIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/w6ifwgp9sg0uqs28pbl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QhpXyFIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/w6ifwgp9sg0uqs28pbl8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Add at tail :
&lt;/h4&gt;

&lt;p&gt;In this case we assumed that we don’t have a pointer of the tail so in order to get that we need to loop over all the list nodes then point the last node next pointer to the new node and point the next pointer of the new node to null so it indicates that it’s the last node.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;you can make this also o(1) if you memorize the tail address &amp;gt;in your implementation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YjFWCykT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2gn6t4fcmk0qq9es7c6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YjFWCykT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2gn6t4fcmk0qq9es7c6g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Add at a specified Index :
&lt;/h4&gt;

&lt;p&gt;First we have to find the node that correspond to that index and for that we need to loop until we reach that node after that it’s just a matter of changing pointers the new node next pointer will point to the current node next and the current node next pointer will point to the new node and . And generally it will take O(n+1/2) time complexity so we can say it’s O(n).&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RJyVrGQF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g37uofo649zqa3cvj3pp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RJyVrGQF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g37uofo649zqa3cvj3pp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Remove Head :
&lt;/h4&gt;

&lt;p&gt;Since we have a head pointer this will be a O(1) time complexity and all what we need to do is :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;make the head pointer point to the current head next pointer then clear the head node.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;in our case in java there is something called the garbage &amp;gt;collector so as long as an object has no reference to it it &amp;gt;will be cleared but in some other language you have to free &amp;gt;the space manually.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X2t7m0YO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sx44lwr16lim6oq6t97u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X2t7m0YO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sx44lwr16lim6oq6t97u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Remove tail :
&lt;/h4&gt;

&lt;p&gt;Just as adding at the tail we need first to find the node that is before tile with a loop then we do the next :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;point the current node next to null. And this will take O(n) time complexity.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RWZQvXN3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/twwdp4eq7o13em5ztssy.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Remove at a specified index :
&lt;/h4&gt;

&lt;p&gt;For this we have to loop over the list nodes so we can get the node that we are deleting after that we can do :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;point the next pointer of node that is before the index to the next of the deleted node.
and it will be an O(n) time complexity.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bhBsSOZg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/keyvo0fopv1hg6n598vj.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Search for a value:
&lt;/h4&gt;

&lt;p&gt;It’s simple just a loop over using a pointer and if we reach the null pointer it means that the element was not found in the list , complexity will be O(n).&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wfaxomiZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ogyz30pqbcmsozityttb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wfaxomiZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ogyz30pqbcmsozityttb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Double linked-lists :
&lt;/h3&gt;

&lt;p&gt;A doubly linked list has the same behaviour as the normal linked list (single linked list) but each node has one more info and that is a pointer to the node that is before him so basically each node has 3 information :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a pointer to node that is before him : before&lt;/li&gt;
&lt;li&gt;a value with a specific type : value.&lt;/li&gt;
&lt;li&gt;a pointer to the next node after him : next.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;the head before pointer and the tail next pointer will be &amp;gt;null as indicator of the start and the end of the list.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How can i implement a double-linked-list ?
&lt;/h3&gt;

&lt;p&gt;Each double linked list has a pointer at the head and the tail of the list and a size proprieties . Each node has tow pointer before and next and a value.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;the implementation can be changed as you want as long as you &amp;gt;keep the same concept because at the end this data structure &amp;gt;is meant to help you not make it more complicated so you can &amp;gt;always tweak the implementation to solve the problem that &amp;gt;you want or add new operations for the list as you need.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Double-Linked-Lists operation complexity :
&lt;/h3&gt;

&lt;p&gt;The code source for the Double linked lists implementation is in this file :&lt;br&gt;
&lt;a href="https://github.com/GourineAyoubPrf/ArrayAndLinkedLists/tree/main/src/arraysandlinkedlistes"&gt;https://github.com/GourineAyoubPrf/ArrayAndLinkedLists/tree/main/src/arraysandlinkedlistes&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Add at head :
&lt;/h4&gt;

&lt;p&gt;The same it’s will stay o(1) and doing the flowing steps :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;point the new node “before” pointer to null.&lt;/li&gt;
&lt;li&gt;Point the “next” pointer of the new node to the head .&lt;/li&gt;
&lt;li&gt;Point the “before” pointer of the head to new node.&lt;/li&gt;
&lt;li&gt;Make the list head pointer points to the new node.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DhX2gktt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0ii6gonixbk6tn6zfu8k.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Add At tail :
&lt;/h4&gt;

&lt;p&gt;This will be O(1) following the next steps , since we have a tail pointer we just need to do :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;point the head “next” pointer to the new node.&lt;/li&gt;
&lt;li&gt;point the new node “before” to the tail of the list.&lt;/li&gt;
&lt;li&gt;point the new node “next” pointer to null.&lt;/li&gt;
&lt;li&gt;make the tail of the list is the new node.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RvCl8w_W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fel61z0557riljir6fgp.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Add at a specified index :
&lt;/h4&gt;

&lt;p&gt;Just as single linked list we need to loop over the list to fond the element with that node , the time complexity will be O(n) and the steps will be the following :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;find the node that correspond to that index (let’s name it node X).&lt;/li&gt;
&lt;li&gt;make the new node “before” pointer point to node X.&lt;/li&gt;
&lt;li&gt;make the new node “next” pointer points to node X “next” pointer.&lt;/li&gt;
&lt;li&gt;the previous “next” node of X (lets name it Y).&lt;/li&gt;
&lt;li&gt;make the “before” pointer of Y points to the new node.&lt;/li&gt;
&lt;li&gt;make node X “next” pointer points to the new node.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xtx1mFxn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4jab0e8r23u872ka6r5e.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Remove at head :
&lt;/h4&gt;

&lt;p&gt;Same as linked list will take O(1) :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lets name the “next” node of the head node X.&lt;/li&gt;
&lt;li&gt;point node X “before’ pointer to null.&lt;/li&gt;
&lt;li&gt;the new head will be node X.&lt;/li&gt;
&lt;li&gt;garbage collector will do the rest since the head has no reference to it it’s space will be freed.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2eatfvk5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nf3qsbcz94zttror7zib.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Remove at tail :
&lt;/h4&gt;

&lt;p&gt;This will take O(1) time complexity with this steps :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;let’s name the node that is before the tails (the before of the tail) node X.&lt;/li&gt;
&lt;li&gt;point the node x “next” pointer to null.&lt;/li&gt;
&lt;li&gt;make the list tail point to the node x.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KQzxPMQL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y3pkj0nc4vg826kb7zos.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  remove at a specified index :
&lt;/h4&gt;

&lt;p&gt;This will be O(n) :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;first we need to find the node correspond to the index and we use 2 pointers.&lt;/li&gt;
&lt;li&gt;let’s name the node at the index node X.&lt;/li&gt;
&lt;li&gt;lets name the node before the node X node Y&lt;/li&gt;
&lt;li&gt;lets name the node that is after node X node Z.&lt;/li&gt;
&lt;li&gt;point node node Y “next” to node Z.&lt;/li&gt;
&lt;li&gt;point node Z “before” to the node Y.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UN3dMAUl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3ufnc0a901dgmt4aggy8.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;the search operation is the same it will take O(n) time &amp;gt;complexity and the we use the same principal in searching &amp;gt;just a pointer that will loop until we reach the end.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Single linked list vs double linked list :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;single linked list will have no “before” pointer mean;s you can’t go backward but in the same time it will store less data.&lt;/li&gt;
&lt;li&gt;with double linked list you will have the ability to go through list in the tow direction but with the cost that it has more space cause it has 1 more information to store.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Circular linked List :
&lt;/h3&gt;

&lt;p&gt;Circular linked list is another linked list type basically it;s the same as the double linked list but instead of the head before pointer point to null adn the tail next pointer point to null we have :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the before pointer of the head will point to the list tail.&lt;/li&gt;
&lt;li&gt;the next pointer of the tail will point to the list head.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in this way the list will be circular in a way that you will loop over the list nodes as long as you want with no stop unless you store the head address or the tail address and check for them in order to stop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;arrays and linked list are tow of the most commune Data structures so any programmer or a software engineer need to know and understand how they work.&lt;/li&gt;
&lt;li&gt;when you want to choose what to use between arrays and linked list try to see what;s the most commune operation that will be done in your algorithm then base on that take the data structure that does that operation with less time complexity , as you know there is no good or bad data structure it;s all about what you are using in for.&lt;/li&gt;
&lt;li&gt;when you are using a programming language try to see the implementation and the method given to the data structure that you are using cause it may be different from one language to another.&lt;/li&gt;
&lt;li&gt;knowing the difference between how the linked list get stored in memory and how the dynamic arrays are stored in memory is so important not because they are both dynamic means that they have the same time complexity .&lt;/li&gt;
&lt;li&gt;hope you had a good reading and you benefited from the article , next article will be about tow other linear data structures : stacks and queues. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;this article is also available in the medium website you can &amp;gt;visit this link :&lt;br&gt;&lt;br&gt;
&lt;a href="https://gourineayoub-prf.medium.com/data-structures-and-complexity-part2-linear-data-part1-arrays-and-linked-lists-713a53360e64"&gt;https://gourineayoub-prf.medium.com/data-structures-and-complexity-part2-linear-data-part1-arrays-and-linked-lists-713a53360e64&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>algorithms</category>
      <category>beginners</category>
      <category>datastructures</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Data structure and complexity a programmer best tow weapons (part 1 : introduction)</title>
      <dc:creator>GourineAyoubPrf</dc:creator>
      <pubDate>Fri, 04 Dec 2020 17:50:22 +0000</pubDate>
      <link>https://dev.to/gourineayoubprf/data-structure-and-complexity-a-programmer-best-tow-weapons-part-1-introduction-2hh0</link>
      <guid>https://dev.to/gourineayoubprf/data-structure-and-complexity-a-programmer-best-tow-weapons-part-1-introduction-2hh0</guid>
      <description>&lt;p&gt;Being a software engineer does not mean only that you should know how to build programmes it also means that you should aim for the best performance that you can get from what you are building to give the user the best experience , in order to do that as a software engineer you should know the different types of DS’s (data structures) and how to use theme plus how to get the best out of your solution using the complexity analysing.&lt;br&gt;
Data structures :&lt;/p&gt;

&lt;h3&gt;
  
  
  Definition :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;My definition : data structure is a way of organizing data with some specific rules in order to solve various programming problems , each data structure has it’s own pros and cons or more like a place where it will be best to use it based on what it can offer to the programmer , each data structure has it’s own operations and relations between the data that it contains also the nature of the data that is stored in it.&lt;/li&gt;
&lt;li&gt;wiki : a data structure is a data organization, management, and storage format that enables efficient access and modification.More precisely, a data structure is a collection of data values, the relationships among them, and the functions or operations that can be applied to the data&lt;/li&gt;
&lt;li&gt;A data structure is a specialized format for organizing, processing, retrieving and storing data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  why we use data structures ?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;we use data structures as a tool for storing any kind of data that we are manipulating in our algorithm.&lt;/li&gt;
&lt;li&gt;Data structures are used in computing to make it easy to locate and retrieve information.&lt;/li&gt;
&lt;li&gt;without DS (Data structures) it will be impossible to treat a huge amount of data with no errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  why you should learn data structures ?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;if you know a lot of DS it’s guaranteed that you will use the right DS in the right place.&lt;/li&gt;
&lt;li&gt;knowing more DS will make give you the ability to know how to lower the complexity (we will talk about it later ) and maximize the performance of your algorithms.&lt;/li&gt;
&lt;li&gt;a lot of famous algorithms is implemented in some specific DS so to understand it you have to understand the DS that is implemented with.&lt;/li&gt;
&lt;li&gt;you will have more than one solution for your problems so that you can choose the best one .&lt;/li&gt;
&lt;li&gt;save memory by using the best fit DS for your algorithms.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Data structures types :
&lt;/h3&gt;

&lt;p&gt;there is a lot of DS each one has it’s own rules,way of manipulating,relations between it’s data , the format of it’s stored data , complexity but on general we can group the DSs in four forms :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;linear : list , arrays , stack ,queues, linked lists.&lt;/li&gt;
&lt;li&gt;trees : binary tree , AVL tree , black/red tree. , heaps …etc.&lt;/li&gt;
&lt;li&gt;hashes : hash-maps , hash-tables.&lt;/li&gt;
&lt;li&gt;graphs : decision, directed … etc&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;note : we will discuss each DS in depth in the next parts &amp;gt;of this articles series.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Types of operations that can we make for a data structure :
&lt;/h3&gt;

&lt;p&gt;As a DS is way of organizing and manipulating data it means that we can apply some operation on the data that we are storing and basically the operation can be one of this following or ones that are similar to it :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;adding / pushing .&lt;/li&gt;
&lt;li&gt;removing / deleting .&lt;/li&gt;
&lt;li&gt;updating .&lt;/li&gt;
&lt;li&gt;sorting .&lt;/li&gt;
&lt;li&gt;merging .&lt;/li&gt;
&lt;li&gt;retrieving.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;note :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there is also other operation that can be done only to &amp;gt;some types of DS , so some operation are based on the type &amp;gt;of the DS that you are using each DS support a bunch of &amp;gt;operation.&lt;/li&gt;
&lt;li&gt;the way of the operation is handled and what is the &amp;gt;result of the operation may be different from one DS to &amp;gt;another based on how it store the data and manipulate it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  what is an algorithm complexity ?
&lt;/h3&gt;

&lt;p&gt;in programming , solving the problem is not everything because some time the solution is not applicable in real world applications or it exceeds the resources that a company have so for the same problem most of the time there is more then one solution , the next step after finding a solution that works for the different test cases is to optimize it , and here we have tow axes that we focus on :&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Time complexity :
&lt;/h4&gt;

&lt;p&gt;it means the time that your algorithm will take to give a correct result after giving it an input (if there is inputs ) and to make it more formal when programmers study the complexity of there solution they use one of the complexity notation as an example big notation (will discuss later). we measure the time and complexity in terms of the growth and and the number of operations relative to the input size n.Usually, the time required by an algorithm falls under three types :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Best Case − Minimum time required for program execution.&lt;/li&gt;
&lt;li&gt;Average Case − Average time required for program execution.&lt;/li&gt;
&lt;li&gt;Worst Case − Maximum time required for program execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. space complexity :
&lt;/h4&gt;

&lt;p&gt;Here we are talking about the amount of space your algorithm will allocate in order to solve the problem most of the time the space will be freed after the end of the algorithm(we are not talking about data base space here) but the problem is when your algorithm consumes a lot of memory by time your program will crush and it will cause the system to crush to.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;note : in this article we focus more on time complexity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Asymptotic bounds :
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b8OtOcKt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k0wdx48v2r0fylgne2qv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b8OtOcKt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k0wdx48v2r0fylgne2qv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;in order to measure the complexity we need some formal ways to do that for each solution and for that we have a 3 Asymptotic bounds :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;big-omega : which gives you the lower bound.&lt;/li&gt;
&lt;li&gt;big-o : which gives you the upper bound.&lt;/li&gt;
&lt;li&gt;big-theta : which gives you both the upper and lower bound.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;note :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The annotation it self is not related to the best,worst or &amp;gt;average solution , each annotation can be applied to &amp;gt;calculate worst, best or average of the solution that you &amp;gt;have done.&lt;/li&gt;
&lt;li&gt;big-Theta is good because it gives you both bounds but &amp;gt;it’s hard sometimes to prove it .&lt;/li&gt;
&lt;li&gt;if big-theta of a function f is X then it means that big-o &amp;gt;of this function f is also X but not the inverse unless that &amp;gt;big-omega is also equals to X.&lt;/li&gt;
&lt;li&gt;the Asymptotic bounds are based on a mathematical &amp;gt;functions and they allow you to give a complexity to a &amp;gt;solution that you implemented and by result you can compare &amp;gt;tow solutions and take the best based on that.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How to calculate Big-o notation ?
&lt;/h3&gt;

&lt;p&gt;big-o is a notation used to the upper bound time of an algorithm it means the worst case scenario which we always get interested in because if the worst case is good for the you don’t have to worry about other cases.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;note : some operation like push /pull / add has different &amp;gt;complexities based on the type of the data structure that &amp;gt;you are using as an example : to search for a value in a &amp;gt;hash-table DS that will be O(1) in best case and o(n) in &amp;gt;some other cases (hash collision cases) but in a linked-List &amp;gt;that will always be O(n).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  asymptotic notations for the big-o :
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. constant O(1):
&lt;/h4&gt;

&lt;p&gt;basically each simple instruction in your algorithm has a constant time complexity noted as O(1) this simple instruction are operations like this :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a variable declaring.&lt;/li&gt;
&lt;li&gt;a value assigning to a variable.&lt;/li&gt;
&lt;li&gt;a condition test.&lt;/li&gt;
&lt;li&gt;accessing an array value by index.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ee2EujYs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9cokkj5j2mfuxosjp33w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ee2EujYs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9cokkj5j2mfuxosjp33w.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. logarithmic O(log n):
&lt;/h4&gt;

&lt;p&gt;An algorithm is said to run in logarithmic time if its time execution is proportional to the logarithm of the input size. usually this type of complexity will exist if the number of iteration that you are doing in your program will get divided to half each iteration as an example : first iteration : 20 → second iteration : 10 → third iteration : 5 … etc.&lt;/p&gt;

&lt;p&gt;This kind of behaviour is used in a one of the best algorithm paradigm know as divide and concur an as an example we have the binary search of a value in a sorted array :&lt;/p&gt;

&lt;p&gt;in this algorithm the number of iteration is divided to half each time and we choose the half that we continue with based on the value of the searched element so the complexity here will be O(log n).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;note : the data can be divided by more then 2 (in this case &amp;gt;the logarithm base get changed as example : divide by tow it &amp;gt;means log base 2 and if you divide by 4 it means log base 4 &amp;gt;…etc).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4IcjQ-jk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/q6r2guesydv4znjl7z7v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4IcjQ-jk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/q6r2guesydv4znjl7z7v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. linear O(n) :
&lt;/h4&gt;

&lt;p&gt;Linear time complexity will appear when we have to do a simple instruction but n times usually that n refers to the length of a data structures that we will loop overt it’s elements or a counter in a loop as an example a for loop with a condition of index&amp;lt; n where n is the length of our list :&lt;/p&gt;

&lt;p&gt;so the complexity of this loop here is the complexity of the condition + the complexity of the loop core * n (number of repetitions) and since we take the worst case in big-o so we say that this complexity = O(1) + O(n) = O(n)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;note : if the condition contains a function call or the loop &amp;gt;core itself contains a function call then we need to take &amp;gt;that in consideration and calculate the called function &amp;gt;complexity first then we multiply it by n(number of repetitions).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mFwoZeyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iz4hupaqvc88chma5qwo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mFwoZeyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iz4hupaqvc88chma5qwo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. n log n complexity O(n log n) :
&lt;/h4&gt;

&lt;p&gt;As we already talked about the O(log n) and the O(n) complexity the O(n log n) is just a form of repeating the log n complexity n times as an example we can take the quick sort algorithm as an example where the data will be divided and treat each half and sort it and repeat this until the table is sorted so we have the divide and concur mechanism that will take O(log n) time complexity and O(n) time complexity for the iteration through the table , in this implementation we are using a recursive mechanism :&lt;/p&gt;

&lt;p&gt;the formula of complexity (because it;s recursive) is T(n) = 2T(n/2) + O(n) and after you solve it you will have a complexity of O(n log n).&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y0hmz7yD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ey6rxhm6yz8lnv4y2508.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y0hmz7yD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ey6rxhm6yz8lnv4y2508.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4. quadratic O(n²):
&lt;/h4&gt;

&lt;p&gt;this complexity appears often when we have a nested loop (a loop inside another loop) as in example the algorithm that prints all the elements of a matrix will be like this :&lt;/p&gt;

&lt;p&gt;in this case we have the first loop that will repeat I times and inside it each time the second loop will repeat j times and since we consider the number of repeated times as n so we have n repeated n times so its O(n2)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;note : In general, doing something with every item in one &amp;gt;dimension is linear, doing something with every item in two &amp;gt;dimensions is quadratic, and dividing the working area in &amp;gt;half is logarithmic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4NQ3ktAR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f3b2iptg5dwcmkytbpmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4NQ3ktAR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f3b2iptg5dwcmkytbpmg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5. cubic O(n³) :
&lt;/h4&gt;

&lt;p&gt;Here we have the same principal as the quadratic complexity but we add one nested loop inside so it will be 3 loops as an example we have this situation : a list that has a matrix as a value and we need to loop every matrix and print it’s values.&lt;/p&gt;

&lt;p&gt;since we already know that the complexity of the matrix print algorithm is O(n2) the we just have to multiply it by n and that give us O(n3).&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nWbuYDe9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ecq4wb8deo1p3usg4dpz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nWbuYDe9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ecq4wb8deo1p3usg4dpz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  6. exponential O(2^n) :
&lt;/h4&gt;

&lt;p&gt;so we already know that in the logarithmic complexity the data is divided by tow but here we have the complexity will grow after each iteration , this is more likely to happen with recursive calls as an example the Fibonacci sequence algorithm :&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v4pZEGDK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qktps2fdm8gmu6kgpwkn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v4pZEGDK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qktps2fdm8gmu6kgpwkn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  7. factorial O(n!) :
&lt;/h4&gt;

&lt;p&gt;this is one of the worst complexity that you should always avoid (if you can) and it appears in the problem of finding Find all permutations of a given set/string.&lt;/p&gt;

&lt;h3&gt;
  
  
  complexity for recursive functions :
&lt;/h3&gt;

&lt;p&gt;for recursive function it’s a bit different to calculate the complexity since we have to do a mathematical analyses of the algorithm and proof it complexity throw the iterations , and there is also many rules depends on the shape of the recursive functions , example :&lt;/p&gt;

&lt;p&gt;if we take the Fibonacci algorithm as an example and try to analyse it’s complexity we will find the next :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;the if condition and the return 1 will always be of complexity O(n)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;this line {return Fibonacci(n-1) + Fibonacci(n-2) } has tow functions calls it means in order to calculate it’s complexity we need to calculate the called functions complexity and since it the same function called in a recursively we need to format it in a formula :&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Where T(n) = our complexity and n = the number that we want to calculate for the Fibonacci sequence. And c is a constant with O(1) complexity represent the first part before the functions call.&lt;/p&gt;

&lt;p&gt;1et iteration : T(n) = T(n -1) + T(n-2) + c =&lt;/p&gt;

&lt;p&gt;2end iteration : T(n) = 2 (T(n-1) + T(n-2) + c) + c&lt;/p&gt;

&lt;p&gt;3ed iteration : T(n) = 2(2 (T(n-1) + T(n-2) + c) + c) + c&lt;/p&gt;

&lt;p&gt;……&lt;/p&gt;

&lt;p&gt;k iteration : 2^k * T(n — 2k) + (2^k — 1)*c // approximation.&lt;/p&gt;

&lt;p&gt;After this you need to find the k value and replace it in the last formula to find the complexity. For this solution the complexity will be O(2^n)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;note 1 : each recursive function will be solved in a &amp;gt;different way depends on the number of calls that it has and &amp;gt;the way of the data is handled (is the data getting smaller &amp;gt;by dividing or by subtracting a value from it …etc).&lt;/p&gt;

&lt;p&gt;note 2 : sometimes to make the complexity better consider &amp;gt;using another approach for solving the same problem as an &amp;gt;example if you are using recursive way try using dynamic &amp;gt;programming (this paradigm will be discussed in the next &amp;gt;articles).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  conclusion :
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Data structures is a major thing that you need to know at least the famous and most used of theme in order to become a better programmer , each time you learn a new DS you will have a new view or a new perspective on how to solve a problem based on the philosophy of that new DS and the more you get used to different DS the more different solution you can get for the same problem and the most important you will know which DS is the best to use with that problem ion order to give you the best performance.&lt;/li&gt;
&lt;li&gt;Time and Space complexity is a one of the important axis that based on we judge the efficiency and the quality of the solution and it goes along side with understanding the DS that you work with because if you don’t then you can’t neither calculate the complexity of your solution nor optimizing it .&lt;/li&gt;
&lt;li&gt;the more you solve programming problems and try to optimize them the more you will get experience and get to know a variant of new DSs , make sure you do your best and keep learning every day “ we are never old to learn new things “.&lt;/li&gt;
&lt;li&gt;hope you got some new information from this article and it benefited you , this article is just the first from a series of article that will discus different Data structures and it’s complexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;this article is also posted on meduime : &lt;a href="https://gourineayoub-prf.medium.com/data-structure-and-complexity-a-programmer-best-tow-weapons-part-1-introduction-a941cda2f557"&gt;https://gourineayoub-prf.medium.com/data-structure-and-complexity-a-programmer-best-tow-weapons-part-1-introduction-a941cda2f557&lt;/a&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>beginners</category>
      <category>datastructures</category>
      <category>complexity</category>
    </item>
  </channel>
</rss>
