diff --git a/Data-Structure-Arrays.md b/Data-Structure-Arrays.md index a3279570c..3969a832e 100644 --- a/Data-Structure-Arrays.md +++ b/Data-Structure-Arrays.md @@ -4,6 +4,58 @@ Internally, `array` is a kind of data structure that can store a fixed-size sequ `array` consists of contiguous memory locations. The lowest address corresponds to the first element and the highest address to the last element. + +## Arrays in C++ + +C++ provides a data structure, `array`, which stores a fixed-size sequential collection of elements of the same data-type. An `array` is used to store a collection of data, but it is better to think of an `array` as a collection of variables of the same type. + +#### Declaration of `array` + +```cpp + +int intarray[10]; // Declares an array of integer type of size 10 with elements having random values. Index ranges from 0 to 9(i.e. size-1). +int intarray[10] = { 0 }; // Declares an array of integer of size 10 with all elements having value 0 + +// Choose one the two declarations and then move ahead. + +``` + +#### Inserting elements to `array`: + +```cpp + +intarray[0] = 1; // Inserts an integer value of 1 at index 0 +intarray[1] = 0; // Inserts an integer value of 0 at index 1 +intarray[2] = -1; // Inserts an integer value of -1 at index 2 +intarray[3] = 1; // Inserts an integer value of 1 at index 3 + +``` + +#### Printing an `array`: + +```cpp + +std::cout << intarray[0] << std::endl; // Returns 1 which is element at index of the array +std::cout << intarray[11] << std::endl; // A random number is expected, while in reality this is `dangerous`, and is primary cause of crashes as it's accessing a memory location which does not exist. + +// To print all the elements of the array +for(int i = 0; i < n; i++) + std::cout << intarray[i] << std::endl; + +``` + +#### Basic operations on `array`: + +```cpp + +std::cout << sizeof(intarray)/sizeof(intarray[0]) << std::endl; // Returns the length of the array i.e. 10. +std::cout << sizeof(intarray[0]) << std::endl; // Returns length in bytes of one array item i.e. 4 as it is an integer + +``` + +:rocket: [Run Code](https://repl.it/CWZE/3) + + ## Arrays in Python Python doesn't have a native `array` data structure. An `array` in Python should not be confused with `list`. The major difference between a `list` @@ -12,47 +64,55 @@ and an `array` in Python is that a `list` can have different types of values whe #### Declaration of `array` ```python + from array import array intarray = array('i') # Declares an array of integer type + ``` -#### Adding elements to `array`: +#### Inserting elements to `array`: ```python -intarray.append(1) # Adds an integer value of 1 to the array -intarray.append(0) # Adds an integer value of 0 to the array -intarray.append(-1) # Adds an integer value of -1 to the array -intarray.append(1) # Again adds an integer value of 1 to the array -intarray.append('d') # Would give a TypeError as the array is of integer type. +intarray.append(1) # Inserts an integer value of 1 to the array +intarray.append(0) # Inserts an integer value of 0 to the array +intarray.append(-1) # Inserts an integer value of -1 to the array +intarray.append(1) # Inserts an integer value of 1 to the array + +intarray.append('d') # Would give a TypeError as the array is of integer type. #Resolve the above error and then move ahead. + ``` -#### Printing an `array`: +#### Printing an `array`: ```python + print(intarray) # Returns array('i', [1, 4, -1]) print(intarray[0]) # Returns 1 which is the element at index 0 of the array -print(intarray[3]) # Would give IndexError as there is no element at index 3 of array. +print(intarray[3]) # Would give IndexError as there is no element at index 3 of array. #Resolve the above error and then move ahead. - + # To print all the elements of the array for i in intarray: print(i) + ``` -#### Basic operations on `array`: +#### Basic operations on `array`: ```python + len(intarray) # Returns the length of the array i.e. 3 intarray.itemsize # Returns length in bytes of one array item i.e. 4 as it is an integer intarray.count(1) # Returns the number of occurrences of 1 in the array i.e. 2 intarray.insert(1, 3) # Insert a new item with value x in the array before position i intarray.remove(1) # Remove the first occurrence of 1 from the array intarray.reverse() # Reverse the order of the items in the array -intarray.pop(1) # Removes the item with the index 1 from the array and returns it +intarray.pop(1) # Removes the item with the index 1 from the array and returns it + ``` :rocket: [Run Code](https://repl.it/CWJB) diff --git a/Data-Structure-Linked-Lists.md b/Data-Structure-Linked-Lists.md new file mode 100644 index 000000000..285c7916c --- /dev/null +++ b/Data-Structure-Linked-Lists.md @@ -0,0 +1,468 @@ +# Linked list + + Just like a garland is made with flowers, a linked list is made up of nodes. We call every flower on this particular garland to be a node. And each of the node points to the next node in this list as well as it has data (here it is type of flower). + +## Types + +1. Singly Linked List + + Singly linked lists contain nodes which have a `data` field as well as a `next` field, which points to the next node in the sequence. Operations that can be performed on singly linked lists are insertion, deletion and traversal. + + ``` + + Singly Link List + -------------- + + head + | + | + +-----+--+ +-----+--+ +-----+------+ + | 1 |o-----> | 2 |o-----> | 3 | NULL | + +-----+--+ +-----+--+ +-----+------+ + + ``` + + Application + + Internal implementation of CPython, the frames and evaluated variables are kept on a stack. + + For this we need to iterate only forward aur get the head, therefore singly linked-list is used. + +2. Doubly Linked List + + Doubly linked lists contain node which have `data` field, `next` field and another link field `prev` pointing to the previous node in the sequence. + + ``` + + Doubly Linked List + ---------------- + + head + | + | + +------+-----+--+ +--+-----+--+ +-----+------+ + | | |o------> | |o------> | | | + | NULL | 1 | | 2 | | 3 | NULL | + | | | <------o| | <------o| | | + +------+-----+--+ +--+-----+--+ +-----+------+ + + ``` + + Application + + The browser cache which allows you to hit the BACK and FORWARD button. Here we need to maintain a doubly linked list, with `URLs` as data field, to allow access in both direction. To go to previous URL we will use `prev` field and to go to next page we will use `next` field. + +3. Circular Linked List + + Circular linked lists is a singly linked list in which last node, `next` field points to first node in the sequence. + + ``` + + Circular Linked List + ------------------ + + head + | + | + +-----+--+ +-----+--+ +-----+--+ + --> | 1 |o-----> | 2 |o-----> | 3 |o---- + | +-----+--+ +-----+--+ +-----+--+ | + | | + ------------------------------------------------ + + ``` + + Application + + Timesharing problem solved by the operating system. + + In a timesharing environment, the operating system must maintain a list of present users and must alternately allow each user to use a small portion of CPU time, one user at a time. The operating system will pick a user, let him/her use a small amount of CPU time and then move on to the next user. + + For this application, there should be no NULL pointers unless there is absolutely no one requesting CPU time, i.e list is empty. + + +## Basic Operations + +1. Insertion + + To add a new element to the list. + + ``` + + Insertion at the beginning + ------------------------ + + * Create a new node with given data. + * Point new node's `next` to old `head`. + * Point `head` to this new node. + + Insertion in the middle/end + -------------------------- + Insertion after node X. + + * Create a new node with given data. + * Point new node's `next` to old X's `next`. + * Point X's `next` to this new node. + + ``` + Time Complexity: O(1) + +2. Deletion + + To delete existing element from the list. + + ``` + + Deletion at the beginning + ----------------------- + + * Get the node pointed by `head` as Temp. + * Point `head` to Temp's `next`. + * Free memory used by Temp node. + + Deletion in the middle/end + ------------------------- + Deletion after node X. + + * Get the node pointed by `X` as Temp. + * Point X's `next` to Temp's `next`. + * Free memory used by Temp node. + + ``` + Time Complexity: O(1) + +3. Traversing + + To travel acroos the list. + + ``` + + Traversal + -------- + + * Get the node pointed by `head` as Current. + * Check if Current is not null and display it. + * Point Current to Current's `next` and move to above step. + + ``` + Time Complexity: O(n) // Here n is size of link-list + +## Implementation + +### C++ implementation of singly linked list + +```cpp + +// Header files +#include + +struct node +{ + int data; + struct node *next; +}; + +// Head pointer always points to first element of the linked list +struct node *head = NULL; + +``` + +#### Printing data in each node + +```cpp + +// Display the list +void printList() +{ + struct node *ptr = head; + + // Start from the beginning + while(ptr != NULL) + { + std::cout << ptr->data << " "; + ptr = ptr->next; + } + + std::cout << std::endl; +} + +``` + +#### Insertion at the beginning + +```cpp + +// Insert link at the beginning +void insertFirst(int data) +{ + // Create a new node + struct node *new_node = new struct node; + + new_node->data = data; + + // Point it to old head + new_node->next = head; + + // Point head to new node + head = new_node; + + std::cout << "Inserted successfully" << std::endl; +} + +``` + +#### Deletion at the beginning + +```cpp + +// Delete first item +void deleteFirst() +{ + // Save reference to head + struct node *temp = head; + + // Point head to head's next + head = head->next; + + // Free memory used by temp + temp = NULL: + delete temp; + + std::cout << "Deleted successfully" << std::endl; +} + +``` + +#### Size + +```cpp + +// Find no. of nodes in link list +void size() +{ + int length = 0; + struct node *current; + + for(current = head; current != NULL; current = current->next) + { + length++; + } + + std::cout << "Size of Linked List is " << length << std::endl; +} + +``` + +#### Searching + +```cpp + +// Find node with given data +void find(int data){ + + // Start from the head + struct node* current = head; + + // If list is empty + if(head == NULL) + { + std::cout << "List is empty" << std::endl; + return; + } + + // Traverse through list + while(current->data != data){ + + // If it is last node + if(current->next == NULL){ + std::cout << "Not Found" << std::endl; + return; + } + else{ + // Go to next node + current = current->next; + } + } + + // If data found + std::cout << "Found" << std::endl; +} + +``` + +#### Deletion after a node + +```cpp + +// Delete a node with given data +void del(int data){ + + // Start from the first node + struct node* current = head; + struct node* previous = NULL; + + // If list is empty + if(head == NULL){ + std::cout << "List is empty" << std::endl; + return ; + } + + // Navigate through list + while(current->data != data){ + + // If it is last node + if(current->next == NULL){ + std::cout << "Element not found" << std::endl; + return ; + } + else { + // Store reference to current node + previous = current; + // Move to next node + current = current->next; + } + + } + + // Found a match, update the node + if(current == head) { + // Change head to point to next node + head = head->next; + } + else { + // Skip the current node + previous->next = current->next; + } + + // Free space used by deleted node + current = NULL; + delete current; + std::cout << "Deleted succesfully" << std::endl; +} + +``` + +:rocket: [Run Code](https://repl.it/CXVt/1) + + +### Python Implementation of Singly Linked List + +```python + +class Node(object): + # Constructor + def __init__(self, data=None, next=None): + self.data = data + self.next = next + + # Function to get data + def get_data(self): + return self.data + + # Function to get next node + def get_next(self): + return self.next + + # Function to set next field + def set_next(self, new_next): + self.next = new_next + + +class LinkedList(object): + def __init__(self, head=None): + self.head = head + +``` + +#### Insertion + +```python + + # Function to insert data + def insert(self, data): + # new_node is a object of class Node + new_node = Node(data) + new_node.set_next(self.head) + self.head = new_node + print("Node with data " + str(data) + " is created succesfully") + +``` + +#### Size + +```python + + # Function to get size + def size(self): + current = self.head + count = 0 + while current: + count += 1 + current = current.get_next() + print("Size of link list is " + str(count)) + +``` + +#### Searching + +```python + + # Function to search a data + def search(self, data): + current = self.head + found = False + while current and found is False: + if current.get_data() == data: + found = True + else: + current = current.get_next() + if current is None: + print("Node with data " + str(data) + " is not present") + else: + print("Node with data " + str(data) + " is found") + +``` + +#### Deletion after a node + +```python + + # Function to delete a node with data + def delete(self, data): + current = self.head + previous = None + found = False + while current and found is False: + if current.get_data() == data: + found = True + else: + previous = current + current = current.get_next() + if current is None: + print("Node with data " + str(data) + " is not in list") + elif previous is None: + self.head = current.get_next() + print("Node with data " + str(data) + " is deleted successfully") + else: + previous.set_next(current.get_next()) + print("Node with data " + str(data) + " is deleted successfully") + +``` + +:rocket: [Run Code](https://repl.it/CVq3/2) + + +**Advantages** + +1. Linked lists are a dynamic data structure, which can grow and shrink, allocating and deallocating memory while the program is running. +2. Insertion and deletion of node are easily implemented in a linked list at any position. + +**Disadvantages** + +1. They use more memory than arrays because of the memory used by their pointers (`next` and `prev`). +2. Random access is not possible in linked list. We have to access nodes sequentially. +3. It's more complex than array. If a language supports array bound check automatically, Arrays would serve you better. + +#### Note + +We have to use free() in C and delete in C++ to free the space used by deleted node, whereas, in Python and Java free space is collected automatically by garbage collector. diff --git a/Data-Structures-Trie.md b/Data-Structures-Trie.md index e9c133349..1ba440676 100644 --- a/Data-Structures-Trie.md +++ b/Data-Structures-Trie.md @@ -21,9 +21,12 @@ This is an image of a Trie, which stores the words {assoc, algo, all, also, tree ## How to implement a trie? +### Python Implementation + Let's implement a trie in python, for storing words with their meanings from english dictionary. ```python + ALPHABET_SIZE = 26 # For English class TrieNode: @@ -31,6 +34,7 @@ class TrieNode: self.edges = [None]*(ALPHABET_SIZE) # Each index respective to each character. self.meaning = None # Meaning of the word. self.ends_here = False # Tells us if the word ends here. + ``` As you can see, edges are 26 in length, each index referring to each character in the alphabet. 'A' corresponding to 0, 'B' to 1, 'C' to 2 ... 'Z' to 25th index. If the character you are looking for is pointing to `None`, that implies the word is not there in the trie. @@ -48,6 +52,7 @@ Additionally, one can also add something like #### Adding Word to the trie ```python + def add_word(self,word,meaning): if len(word)==0: self.ends_here = True # Because we have reached the end of the word @@ -68,6 +73,7 @@ Additionally, one can also add something like #### Retrieving data ```python + def search_word(self,word): if len(word)==0: if self.ends_here: @@ -86,6 +92,7 @@ Additionally, one can also add something like The `search_word` function will tell us if the word exists in the Trie or not. Since ours is a dictionary, we need to fetch the meaning as well, now lets declare a function to do that. ```python + def get_meaning(self,word): if len(word)==0 : if self.ends_here: @@ -98,6 +105,7 @@ The `search_word` function will tell us if the word exists in the Trie or not. S return "Word doesn't exist in the Trie" else: return self.edges[index].get_meaning(word[1:]) + ``` #### Deleting data @@ -105,6 +113,7 @@ The `search_word` function will tell us if the word exists in the Trie or not. S By deleting data, you just need to change the variable `ends_here` to `False`. Doing that doesn't alter the prefixes, but stills deletes the meaning and the existence of the word from the trie. ```python + def delete_word(self,word): if len(word)==0: if self.ends_here: @@ -119,6 +128,7 @@ By deleting data, you just need to change the variable `ends_here` to `False`. D return "Word doesn't exist in the Trie" else: return self.edges[index].delete_word(word[1:]) + ``` :rocket: [Run Code](https://repl.it/CWbr) diff --git a/insertion-sort.md b/insertion-sort.md new file mode 100644 index 000000000..885fa1e01 --- /dev/null +++ b/insertion-sort.md @@ -0,0 +1,113 @@ +# Insertion Sort + +Insertion sort is a [comparision based sorting](https://en.wikipedia.org/wiki/Comparison_sort). A sorting algorithm is comparison based, if it uses comparison operators (such as `less than` and `greated than`) to find the order between two numbers. + +In this sorting technique, we always maintain a sorted sublist in lower position of list and then we take one element from the rest of list and insert it at it's correct place. We does so till all elements are inserted into sublist. For example, while playing cards we sort cards in our hand. Starting from left and moving to right, we keep on inserting the card at it's right place till end. + +## Example + +![Insertion Sort](https://cloud.githubusercontent.com/assets/13117482/15633518/04ca4468-25cc-11e6-96af-feb395b456e0.png) + +In the above example, `grey shaded` sublist is always sorted. Please note that in the beginning, sublist contains ony one element, and *trivially* sorted. Then at each step we are inserting leftmost element of `white shaded` sublist at it's correct position. + +Hence, we have sorted the complete list in this way. + +## Algorithm + +``` + +Loop for i=0 to N-1: +* Pick element array[i] and insert it into sorted sublist array[0...i-1] + +``` + +## Complexity + +``` + +Space complexity: O(1) // Auxillary/temporary space is used. + +Time complexity: O(n*n) // Two nested for loops are used. + +``` + +## C++ Implementation + +```cpp + +// Function to sort an array using insertion sort +void insertionSort(int arr[], int n) +{ + int i, key, j; + for (i = 1; i < n; i++) + { + key = arr[i]; + j = i-1; + + /* Move elements of arr[0..i-1], that are greater than key, + to one position ahead of their current position */ + while (j >= 0 && arr[j] > key) + { + arr[j+1] = arr[j]; + j = j-1; + } + arr[j+1] = key; // place element key at it's correct place + } +} + +int main() +{ + // array to be sorted + int arr[5] = {12, 11, 13, 5, 6}; + + // call the insertion sort + insertionSort(arr, 5); + + // prints sorted array i.e. 5 6 11 12 13 + for(int i=0; i<5; i++) + std::cout << arr[i] << " "; + return 0; +} + +``` + +:rocket: [Run Code](https://repl.it/CWZq) + +## Python Implementation + +```python + +# Function to perform insertion sort +def insertionSort(arr): + # Traverse through array + for i in range(1, len(arr)): + key = arr[i] + # Move elements of arr[0..i-1], that are greater than key, + # to one position ahead of their current position + j = i-1 + while j>=0 and key < arr[j] : + arr[j+1] = arr[j] + j -= 1 + arr[j+1] = key # place element key at it's correct place + +# array to be sorted +arr = [12, 11, 13, 5, 6] +# call the insertion sort +insertionSort(arr) +# prints sorted array i.e. 5 6 11 12 13 +for i in range(len(arr)): + print(arr[i],end = ' ') + +``` + +:rocket: [Run Code](https://repl.it/CWZi) + +## Advantages + +1. Efficient for small set of data and data set that are almost sorted. +2. Simply implemented. +3. Mostly better than bubble sort and selection sort & generally used with merge sort. + +## Disadvantages + +1. It's less efficient on large set of data than merge sort, heap sort and quick sort.