├── .gitignore ├── LICENSE ├── README.md ├── sort.png └── sortlib.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Abhineet Raj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python sorting and graph alogrithms 2 | ![alt text](https://github.com/abhineetraj1/python-sort-lib/blob/main/sort.png?raw=true) 3 | This repository contains Python implementation of graph and sorting algorithms 4 | 5 | ## Installation 6 | 7 | This program requires Python 3 to run. You can download Python 3 from the official website - https://www.python.org/downloads/ 8 | Usage 9 | ## Sorting algorithms 10 | ### Quick Sort 11 | * Quick Sort is a divide-and-conquer algorithm that partitions an array into two parts, then recursively sorts each part. It selects a pivot element and rearranges the array so that all elements less than the pivot are moved to its left and all elements greater than the pivot are moved to its right. The pivot element is then placed in its final position, and the two subarrays to its left and right are recursively sorted. 12 | * Code 13 | ``` 14 | from sortlib import * 15 | 16 | array=[1,2,3,4] 17 | w = arr_sort.quicksort(array) 18 | 19 | print(w) 20 | ``` 21 | ### Merge Sort 22 | * Merge Sort is a divide-and-conquer algorithm that recursively splits an array into two halves until each subarray contains only one element. It then merges the two subarrays by comparing their elements, resulting in a sorted array. 23 | * Code 24 | ``` 25 | from sortlib import * 26 | 27 | array=[1,2,3,4] 28 | w = arr_sort.mergesort(array) 29 | 30 | print(w) 31 | ``` 32 | * Merge 33 | ``` 34 | from sortlib import * 35 | 36 | array=[1,2,3,4] 37 | w = arr_sort.mergesort(0,5) 38 | 39 | print(w) 40 | ``` 41 | 42 | ### Bubble Sort 43 | * Bubble Sort is a simple sorting algorithm that repeatedly steps through the list, compares adjacent elements and swaps them if they are in the wrong order. The pass through the list is repeated until the list is sorted. 44 | * Code 45 | ``` 46 | from sortlib import * 47 | 48 | array=[1,2,3,4] 49 | w = arr_sort.bubble_sort(array) 50 | 51 | print(w) 52 | ``` 53 | 54 | ### Selection Sort 55 | * Selection Sort is a simple sorting algorithm that sorts an array by repeatedly finding the minimum element from the unsorted part of the array and swapping it with the first element of the unsorted part. This process is repeated until the entire array is sorted. 56 | * Code 57 | ``` 58 | from sortlib import * 59 | 60 | array=[1,2,3,4] 61 | w = arr_sort.selection_sort(array) 62 | 63 | print(w) 64 | ``` 65 | 66 | ### Insertion Sort 67 | * Insertion Sort is a simple sorting algorithm that builds the final sorted array one item at a time. It iterates through the array, comparing each element with the previous elements and inserting the current element into its correct position in the sorted part of the array. 68 | * Code 69 | ``` 70 | from sortlib import * 71 | 72 | array=[1,2,3,4] 73 | arr1 = [0.675, 0.876, 0.345, 0.9875, 0.0123, 0.599] 74 | 75 | w = arr_sort.insertion_sort(array) 76 | w1 = arr_sort.insertion_sort_bucket(arr1) 77 | 78 | print(w1) 79 | print(w) 80 | ``` 81 | ### Shell Sort 82 | * Shell Sort is an efficient sorting algorithm that is a generalization of Insertion Sort. It sorts elements at a certain gap distance, then reduces the gap distance until it reaches 1, at which point the algorithm is identical to Insertion Sort. 83 | * Code 84 | ``` 85 | from sortlib import * 86 | 87 | array=[1,2,3,4] 88 | w = arr_sort.shell_sort(array) 89 | 90 | print(w) 91 | ``` 92 | 93 | ### Heap Sort 94 | * Heap Sort is a comparison-based sorting algorithm that uses a binary heap data structure. It starts by building a heap from the input data, then repeatedly extracts the minimum element from the heap and places it at the end of the sorted array. 95 | * Code 96 | ``` 97 | from sortlib import * 98 | 99 | array=[1,2,3,4] 100 | w = arr_sort.heap_sort(array) 101 | 102 | print(w) 103 | ``` 104 | 105 | ### Counting Sort 106 | * Counting Sort is an algorithm for sorting a collection of objects based on the keys that the objects possess. It operates by counting the number of objects that have each distinct key value, and using arithmetic on those counts to determine the positions of each key value in the output sequence. 107 | * Code 108 | ``` 109 | from sortlib import * 110 | 111 | array=[1,2,3,4] 112 | w = arr_sort.counting_sort(array) 113 | 114 | print(w) 115 | ``` 116 | 117 | ### Bucket Sort 118 | * Bucket Sort is a sorting algorithm that divides the input into several buckets. Each bucket is then sorted using another algorithm or by recursively applying the bucket sorting algorithm. The sorted buckets are then concatenated to obtain the final sorted output. 119 | * Code 120 | ``` 121 | from sortlib import * 122 | 123 | array=[1,2,3,4] 124 | w = arr_sort.bucket_sort(array) 125 | 126 | print(w) 127 | ``` 128 | 129 | ## Graph Alogrithms 130 | 131 | ### Bellman-Ford Algorithm 132 | 133 | * To use the Bellman-Ford Algorithm implementation, create a Graph object and add edges to it using the add_edge() method. Then, call the bellman_ford() method with the starting vertex as argument. 134 | * Code 135 | ``` 136 | from sortlib import* 137 | 138 | sortlib.BGraph(vertices) 139 | sortlib.add_edge(x,y,z) 140 | sortlib.bellman_ford(start_index) 141 | ``` 142 | ### Topological graph 143 | 144 | * A topological graph, also known as a planar graph, is a type of graph that can be drawn in the plane without any of its edges crossing each other. In other words, it is a graph that can be represented by a set of points in the plane (called vertices) and a set of curves connecting these points (called edges), such that no two edges intersect except at their endpoints. 145 | 146 | * Code 147 | ``` 148 | from sortlib import * 149 | 150 | sortlib.TGraph(vertices) 151 | sortlib.add_edge(x,y) 152 | sortlib.topological_sort() 153 | sortlib.topological_sort_util(x, visited, stack) 154 | ``` 155 | 156 | ## Contributing 157 | 158 | If you would like to contribute to this project, please create a pull request. 159 | License 160 | 161 | ## Languages and tools used 162 | 163 |

python

164 | 165 | ## Author 166 | * [abhineetraj1](http://github.com/abhineetraj1) 167 | -------------------------------------------------------------------------------- /sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhineetraj1/python-sort-lib/ffec20995e2274570bf4404d8f45c30ab9bf7306/sort.png -------------------------------------------------------------------------------- /sortlib.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | class arr_sort: 4 | #Quick Sort is a divide-and-conquer algorithm that partitions an array into two parts, then recursively sorts each part. 5 | def quicksort(arr): 6 | if len(arr) <= 1: 7 | return arr 8 | pivot = arr[len(arr)//2] 9 | left = [x for x in arr if x < pivot] 10 | middle = [x for x in arr if x == pivot] 11 | right = [x for x in arr if x > pivot] 12 | return quicksort(left) + middle + quicksort(right) 13 | #Merge Sort is a divide-and-conquer algorithm that recursively splits an array into two halves until each subarray contains only one element. 14 | def mergesort(arr): 15 | if len(arr) <= 1: 16 | return arr 17 | mid = len(arr) // 2 18 | left = arr[:mid] 19 | right = arr[mid:] 20 | left = mergesort(left) 21 | right = mergesort(right) 22 | return merge(left, right) 23 | def merge(left, right): 24 | result = [] 25 | i, j = 0, 0 26 | while i < len(left) and j < len(right): 27 | if left[i] <= right[j]: 28 | result.append(left[i]) 29 | i += 1 30 | else: 31 | result.append(right[j]) 32 | j += 1 33 | result += left[i:] 34 | result += right[j:] 35 | return result 36 | #Bubble Sort is a simple sorting algorithm that repeatedly steps through the list, compares adjacent elements and swaps them if they are in the wrong order. 37 | def bubble_sort(arr): 38 | n = len(arr) 39 | for i in range(n): 40 | for j in range(0, n-i-1): 41 | if arr[j] > arr[j+1]: 42 | arr[j], arr[j+1] = arr[j+1], arr[j] 43 | return arr 44 | #Selection Sort is a simple sorting algorithm that sorts an array by repeatedly finding the minimum element from the unsorted part of the array and swapping it with the first element of the unsorted part. 45 | def selection_sort(arr): 46 | n = len(arr) 47 | for i in range(n): 48 | min_idx = i 49 | for j in range(i+1, n): 50 | if arr[j] < arr[min_idx]: 51 | min_idx = j 52 | arr[i], arr[min_idx] = arr[min_idx], arr[i] 53 | return arr 54 | #Insertion Sort is a simple sorting algorithm that builds the final sorted array one item at a time. 55 | def insertion_sort(arr): 56 | n = len(arr) 57 | for i in range(1, n): 58 | key = arr[i] 59 | j = i-1 60 | while j >= 0 and key < arr[j]: 61 | arr[j+1] = arr[j] 62 | j -= 1 63 | arr[j+1] = key 64 | return arr 65 | #Shell Sort is an efficient sorting algorithm that is a generalization of Insertion Sort. 66 | def shell_sort(arr): 67 | n = len(arr) 68 | gap = n // 2 69 | while gap > 0: 70 | for i in range(gap, n): 71 | temp = arr[i] 72 | j = i 73 | while j >= gap and arr[j-gap] > temp: 74 | arr[j] = arr[j-gap] 75 | j -= gap 76 | arr[j] = temp 77 | gap //= 2 78 | return arr 79 | #Heap Sort is a comparison-based sorting algorithm that uses a binary heap data structure. 80 | def heap_sort(arr): 81 | n = len(arr) 82 | for i in range(n//2 - 1, -1, -1): 83 | heapify(arr, n, i) 84 | for i in range(n-1, 0, -1): 85 | arr[i], arr[0] = arr[0], arr[i] 86 | heapify(arr, i, 0) 87 | return arr 88 | #Counting Sort is an algorithm for sorting a collection of objects based on the keys that the objects possess. 89 | def counting_sort(arr): 90 | n = len(arr) 91 | count = [0] * (max(arr)+1) 92 | output = [0] * n 93 | for i in range(n): 94 | count[arr[i]] += 1 95 | for i in range(1, max(arr)+1): 96 | count[i] += count[i-1] 97 | for i in range(n-1, -1, -1): 98 | output[count[arr[i]]-1] = arr[i] 99 | count[arr[i]] -= 1 100 | for i in range(n): 101 | arr[i] = output[i] 102 | return arr 103 | #Bucket Sort is a sorting algorithm that divides the input into several buckets. 104 | def bucket_sort(arr): 105 | bucket = [] 106 | for i in range(len(arr)): 107 | bucket.append([]) 108 | for j in arr: 109 | index = int(10*j) 110 | bucket[index].append(j) 111 | for i in range(len(arr)): 112 | bucket[i] = insertion_sort(bucket[i]) 113 | k = 0 114 | for i in range(len(arr)): 115 | for j in range(len(bucket[i])): 116 | arr[k] = bucket[i][j] 117 | k += 1 118 | return arr 119 | def insertion_sort(bucket): 120 | for i in range(1, len(bucket)): 121 | temp = bucket[i] 122 | j = i-1 123 | while j >= 0 and temp < bucket[j]: 124 | bucket[j+1] = bucket[j] 125 | j -= 1 126 | bucket[j+1] = temp 127 | return bucket 128 | #A topological graph, also known as a planar graph, is a type of graph that can be drawn in the plane without any of its edges crossing each other. In other words, it is a graph that can be represented by a set of points in the plane (called vertices) and a set of curves connecting these points (called edges), such that no two edges intersect except at their endpoints. 129 | class TGraph: 130 | def __init__(self, vertices): 131 | self.graph = defaultdict(list) 132 | self.V = vertices 133 | def add_edge(self, u, v): 134 | self.graph[u].append(v) 135 | def topological_sort(self): 136 | visited = [False] * self.V 137 | stack = [] 138 | for i in range(self.V): 139 | if not visited[i]: 140 | self.topological_sort_util(i, visited, stack) 141 | return stack[::-1] 142 | def topological_sort_util(self, v, visited, stack): 143 | visited[v] = True 144 | for i in self.graph[v]: 145 | if not visited[i]: 146 | self.topological_sort_util(i, visited, stack) 147 | stack.append(v) 148 | #To use the Bellman-Ford Algorithm implementation, create a Graph object and add edges to it using the add_edge() method. Then, call the bellman_ford() method with the starting vertex as argument. 149 | class BGraph: 150 | def __init__(self, vertices): 151 | self.V = vertices 152 | self.graph = [] 153 | def add_edge(self, u, v, w): 154 | self.graph.append([u, v, w]) 155 | def bellman_ford(self, start): 156 | dist = [float("inf")] * self.V 157 | dist[start] = 0 158 | for i in range(self.V - 1): 159 | for u, v, w in self.graph: 160 | if dist[u] != float("inf") and dist[u] + w < dist[v]: 161 | dist[v] = dist[u] + w 162 | for u, v, w in self.graph: 163 | if dist[u] != float("inf") and dist[u] + w < dist[v]: 164 | print("Negative cycle detected") 165 | return 166 | print("Vertex \t Distance from Source") 167 | for i in range(self.V): 168 | print(f"{i}\t{dist[i]}") 169 | 170 | # Made by Abhineet Raj (https://github.com/abhineetraj1) 171 | --------------------------------------------------------------------------------