{"id":25644051,"url":"https://github.com/nirupamkhanal/dsa","last_synced_at":"2026-07-09T23:31:42.278Z","repository":{"id":255094779,"uuid":"802801639","full_name":"NirupamKhanal/DSA","owner":"NirupamKhanal","description":"Demonstration of pointers, data structures, and algorithms","archived":false,"fork":false,"pushed_at":"2024-10-07T19:17:06.000Z","size":79,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-23T15:42:28.182Z","etag":null,"topics":["algorithms","binary-search","binary-search-tree","data-structures","data-structures-and-algorithms","dsa","hashing","hashtable","hasing-algorith","linked-list","linkedlist","pointers","queue","stack"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NirupamKhanal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-05-19T10:04:19.000Z","updated_at":"2024-10-07T19:17:11.000Z","dependencies_parsed_at":"2024-08-28T00:45:30.073Z","dependency_job_id":"fe1c840d-a8a8-4e03-8e92-d73d57b836bf","html_url":"https://github.com/NirupamKhanal/DSA","commit_stats":null,"previous_names":["nirupamkhanal/pointers"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/NirupamKhanal/DSA","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NirupamKhanal%2FDSA","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NirupamKhanal%2FDSA/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NirupamKhanal%2FDSA/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NirupamKhanal%2FDSA/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NirupamKhanal","download_url":"https://codeload.github.com/NirupamKhanal/DSA/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NirupamKhanal%2FDSA/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35315892,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithms","binary-search","binary-search-tree","data-structures","data-structures-and-algorithms","dsa","hashing","hashtable","hasing-algorith","linked-list","linkedlist","pointers","queue","stack"],"created_at":"2025-02-23T07:31:04.747Z","updated_at":"2026-07-09T23:31:42.273Z","avatar_url":"https://github.com/NirupamKhanal.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Data Structures and Algorithms in C++ and C\n\nThis repository contains various data structures and algorithms implemented in C++ and C. The project is organized into sections that cover Pointers and shell scripts, Data Structures, and Algorithms.\n\n## 1. Pointers and Shell Scripts\n\n### 1.1 Pointers\n\n**Pointers** are variables that store the memory address of another variable. They are one of the most powerful and flexible features in C/C++ programming, enabling dynamic memory management, efficient array handling, and direct manipulation of hardware-level operations. Pointers allow for:\n\n- **Referencing/Pointing** to memory locations.\n- **Passing by reference** to modify variables directly.\n- **Dynamic Memory Allocation** using `new` and `delete` (or `malloc` and `free` in C).\n- **Multiple indirection** with double and triple pointers (pointers to pointers).\n\nKey types of pointers include:\n- **Basic Pointers**: Store the address of a variable.\n- **Smart Pointers**: Automatically manage memory allocation and deallocation (e.g., `shared_ptr`, `unique_ptr` in C++).\n- **Weak Pointers**: Prevent cyclic references in shared ownership scenarios.\n- **Double Pointers**: Pointers to other pointers.\n- **Parameterized Pointers**: Pointers that work with any data type, typically using templates in C++.\n\nCommon use cases of pointers include:\n- Dynamic memory management for arrays and data structures like linked lists and trees.\n- Efficient function parameter passing to avoid copying large data structures.\n- Resource management in complex systems (e.g., file handling, networking buffers).\n\nExample:\n```cpp\nint* ptr = new int(10);  // Dynamic memory allocation\n``` \n\n### 1.2 Makefile\n\nA **makefile** is a **shell script file** that defines a set of tasks to be executed. Here, we create a Makefile for compiling C/C++ programs with pointers and memory management functions.\n\n**Shell Scripts** are executable files written in the `Bash` language, a `Unix` shell and command language. They are widely used for automating repetitive tasks, running multiple commands, and managing system configurations.\n\nA typical shell script consists of a series of commands that can:\n- **Automate compilation processes** (e.g., `MakeFile`).\n- Handle **system administration** tasks like file management, backups, and permissions.\n- Simplify **project builds** by automating the execution of commands in sequence.\n\nIn the context of C/C++ projects, shell scripts are often used to compile and run code, clean up directories, and automate testing.\n\n**Example:**\n\n```bash\n#!/bin/bash\n# A simple bash script to compile and run a C++ program\n\ng++ -o program main.cpp  # Compile the C++ code\n./program                # Run the program\n```\n\n### 1.3 Dynamic Memory Allocation\n\nDynamic memory allocation allows us to allocate memory during runtime using `malloc`, `calloc`, `new`, and `delete` in C/C++.\n\nUse Case: Used in scenarios where the size of the data structure is not known at compile time, such as dynamic arrays, linked lists, and graphs.\n\n```cpp\nint main(int argc, char * argv[]) {\n    int * dynamic_array; \n\n    if(argc != 2) {\n        cout \u003c\u003c \"Usage: \" \u003c\u003c argv[0] \u003c\u003c \" \u003cnum elements\\n\";\n        return 1; \n    }\n\n    int num_elements = atoi(argv[1]);\n    dynamic_array = new int[num_elements]; \n\n    set_all_elements(dynamic_array, 13, num_elements);\n    \n    cout \u003c\u003c \"Printing a dynamically allocated array \" \n        \u003c\u003c \"with \" \u003c\u003c argv[1] \u003c\u003c \" elements.\\n\";\n    \n    for(int i = 0; i \u003c num_elements; ++i) {\n        cout \u003c\u003c \"index[\" \u003c\u003c i \u003c\u003c \"]: \" \u003c\u003c dynamic_array[i] \u003c\u003c endl;\n    }\n    cout \u003c\u003c endl;\n\n    delete[] dynamic_array; \n\n    return 0;\n}\n```\n\n## 2. Data Structures\n\n**Data Structures** are ways of organizing and storing data to facilitate efficient access and modifications. They form the backbone of algorithm design and are critical for solving computational problems in an optimized manner. Different data structures excel at different types of tasks, and the choice of the right data structure can significantly impact the performance of a program.\n\nSome of the most common types of data structures are:\n\n### 2.1 **Linear Data Structures**: \n   - **Arrays**: Fixed-size collections of elements stored sequentially in memory.\n   - **Linked Lists**: Dynamic data structures where elements (nodes) point to the next element, making insertion and deletion efficient.\n   - **Stacks**: Last-In-First-Out (LIFO) structures that allow operations only at one end (push/pop).\n   - **Queues**: First-In-First-Out (FIFO) structures that allow operations at both ends (enqueue/dequeue).\n\n### 2.2 **Tree Data Structures**: \n   - **Binary Trees**: Hierarchical data structures where each node has at most two children (left and right).\n   - **Binary Search Trees (BST)**: A binary tree with the property that the left child is smaller than the parent and the right child is greater.\n   - **AVL Trees**: Self-balancing BSTs where the heights of the left and right subtrees differ by at most one.\n   - **Red-Black Trees (RB Trees)**: Another type of self-balancing BST that ensures the tree remains balanced during insertions and deletions.\n\n### 2.3 **Hash Tables**: \n   A data structure that maps keys to values using a hash function. It provides efficient average-case time complexity for search, insertion, and deletion.\n\n### 2.4 **Graph Data Structures**:\n   A graph consists of a set of nodes (vertices) and edges (connections between nodes). Graphs can be used to model networks, relationships, and traversals.\n\n### 2.5 **Tries (Prefix Trees)**: \n   A specialized tree used to store dynamic sets of strings where common prefixes are shared, making operations like prefix search very efficient.\n\n### Importance of Data Structures\nData structures are essential for:\n- **Efficient storage and retrieval** of data.\n- **Optimized algorithms** for searching, sorting, and organizing information.\n- **Memory management** in applications.\n- **Solving complex problems** like shortest path, sorting, searching, and dynamic programming.\n\nChoosing the right data structure is crucial for reducing the time and space complexity of algorithms, and understanding them is fundamental to good software engineering.\n\n### Use Cases of Data Structures\n- **Arrays**: Used in situations where random access is needed (e.g., accessing elements by index).\n- **Linked Lists**: Ideal when frequent insertions and deletions are needed without shifting elements.\n- **Binary Search Trees**: Useful for maintaining sorted data and performing searches efficiently.\n- **Hash Tables**: Perfect for cases requiring quick lookups (e.g., database indexing, caching).\n- **Tries**: Often used in applications involving text processing, such as autocomplete and spell checking.\n\n## 3. Algorithms\n## Algorithms\n\n**Algorithms** are a set of well-defined instructions or steps to solve a particular problem or perform a specific task. In computer science, algorithms form the core of programming as they guide the computer in processing data, solving problems, and making decisions.\n\nAlgorithms are typically evaluated based on two key criteria:\n\n1. **Time Complexity**: How the execution time of an algorithm grows with the input size. The goal is to minimize the time taken for large input sizes.\n   \n2. **Space Complexity**: How the memory usage of an algorithm grows with the input size. Efficient algorithms use minimal memory while processing data.\n\n### Types of Algorithms\n\n### 3.1 **Sorting Algorithms**:\n   Sorting algorithms rearrange elements in a specific order (e.g., ascending or descending). Popular sorting algorithms include:\n   - **Bubble Sort**: A simple comparison-based algorithm where adjacent elements are repeatedly swapped if they are in the wrong order.\n   - **Merge Sort**: A divide-and-conquer algorithm that recursively splits an array into two halves, sorts them, and then merges them back together.\n   - **Quick Sort**: Another divide-and-conquer algorithm that selects a pivot element, partitions the array around the pivot, and recursively sorts the partitions.\n\n   Sorting algorithms are critical in applications like data analytics, file organization, and searching tasks.\n\n### 3.2 **Search Algorithms**:\n   Searching algorithms find an element within a collection. Common searching algorithms include:\n   - **Linear Search**: Sequentially checks each element in the list until the target is found.\n   - **Binary Search**: Efficient algorithm that works on sorted arrays by repeatedly dividing the search interval in half.\n\n   Search algorithms are essential for tasks like searching in databases, handling requests, and looking up information.\n\n### 3.3 **Greedy Algorithms**:\n   Greedy algorithms make the best possible decision at each step, with the hope of finding a global optimum. Examples include:\n   - **Dijkstra’s Algorithm**: Finds the shortest path between nodes in a weighted graph.\n   - **Kruskal’s Algorithm**: Finds the minimum spanning tree in a graph by selecting edges with the least weight.\n\n   Greedy algorithms are often used in optimization problems, such as network design, scheduling, and resource allocation.\n\n### 3.4 **Dynamic Programming (DP)**:\n   Dynamic programming breaks a problem into smaller overlapping subproblems, solving each only once and storing the results for future use. Examples include:\n   - **Fibonacci Sequence**: DP can optimize the computation of Fibonacci numbers by remembering previously computed values.\n   - **Knapsack Problem**: DP can be used to find the optimal solution to choosing items without exceeding a weight limit.\n\n   DP is especially useful for problems involving optimization and decision-making over time.\n\n### 3.5 **Divide and Conquer**:\n   Divide and conquer algorithms break down a problem into smaller subproblems, solve them independently, and combine their solutions. Examples include:\n   - **Merge Sort** and **Quick Sort**: Both use divide and conquer to sort large datasets.\n   - **Binary Search**: This algorithm divides the search space in half each time, reducing the number of comparisons.\n\n   Divide and conquer algorithms are useful for problems involving large datasets, like sorting, searching, and matrix operations.\n\n### 3.6 **Backtracking**:\n   Backtracking is an algorithmic technique that incrementally builds candidates to a solution and abandons a candidate (\"backtracks\") if it fails to satisfy the conditions of the problem. Examples include:\n   - **Sudoku Solver**: Backtracking can be used to fill in numbers while verifying constraints.\n   - **N-Queens Problem**: Backtracking is used to place queens on a chessboard such that no two queens threaten each other.\n\n   Backtracking is useful in constraint satisfaction problems like puzzles, combinatorics, and optimization.\n\n### Importance of Algorithms\n- **Efficiency**: Algorithms are crucial for optimizing the use of resources (time and space).\n- **Scalability**: Good algorithms can handle growing input sizes efficiently, making them essential for large-scale systems and applications.\n- **Problem Solving**: Algorithms are the tools we use to tackle computational problems, from simple tasks to complex real-world challenges like machine learning, networking, and cryptography.\n\n### Use Cases of Algorithms\n- **Sorting Algorithms**: Used in file systems, databases, search engines, and data analysis.\n- **Search Algorithms**: Used in search engines, recommendation systems, and query processing.\n- **Greedy Algorithms**: Applied in network routing, scheduling problems, and financial modeling.\n- **Dynamic Programming**: Useful in solving optimization problems in finance, operations research, and bioinformatics.\n- **Divide and Conquer**: Critical for handling large datasets, image processing, and numerical simulations.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnirupamkhanal%2Fdsa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnirupamkhanal%2Fdsa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnirupamkhanal%2Fdsa/lists"}