vault backup: 2025-03-16 18:59:42
This commit is contained in:
@@ -5,6 +5,7 @@ This study guide provides an in-depth overview of the Abstract Data Type (ADT) L
|
||||
## 1. Overview of Linear Lists
|
||||
|
||||
A linear list is a sequential collection of elements where each element can be accessed via an index. For instance, an instance of a linear list is represented as (e0, e1, e2, …, en-1), where:
|
||||
|
||||
- $e_i$ denotes the i-th element.
|
||||
- $n$ is the finite size of the list, with n >= 0.
|
||||
- $e_0$ is the first element and en-1 is the last.
|
||||
@@ -54,6 +55,7 @@ Element[0], Element[1], Element[2], ...
|
||||
### 5.1 Array-Based Implementation
|
||||
|
||||
The array-based implementation is straightforward:
|
||||
|
||||
- **Class Declaration**: Define a class for the ArrayLinearList.
|
||||
- **Data Members**: Utilize a protected array (Object[]) for storing elements and a variable to track size.
|
||||
- **Constructor Example**: Create constructors to initiate the list with a default or user-defined size.
|
||||
@@ -68,6 +70,7 @@ A linked list version of the linear list provides dynamic memory allocation, whe
|
||||
## 6. Method Implementations in ADT Linear List
|
||||
|
||||
Each method associated with the ADT Linear List is essential for its functionality:
|
||||
|
||||
- **isEmpty()**: Returns true if the size is 0.
|
||||
- **size()**: Simply returns the count of elements.
|
||||
- **get(int index)**: Requires validating the index with *checkIndex()* before accessing the array.
|
||||
|
@@ -11,13 +11,12 @@ A **data structure** is defined as an arrangement or organization of data in a c
|
||||
An **abstract data type (ADT)** is a model that defines the high-level operations and characteristics of a data structure without delving into its implementation details. Before actually implementing a data structure, it is imperative to establish what operations the ADT should support. For instance, when creating a linked list ADT, one might specify operations such as:
|
||||
|
||||
- Inserting an item into the linked list.
|
||||
|
||||
|
||||
- Deleting an item from the linked list.
|
||||
|
||||
|
||||
- Searching for an item in the linked list.
|
||||
|
||||
|
||||
- Checking if the linked list is empty.
|
||||
|
||||
|
||||
This abstraction helps programmers focus on what functionalities the data structure must provide, rather than how those functionalities will be executed.
|
||||
|
||||
@@ -26,9 +25,8 @@ This abstraction helps programmers focus on what functionalities the data struct
|
||||
Two significant programming principles are reviewed: **abstraction** and **modularization**. Abstraction allows programmers to handle complex systems by focusing on high-level functionalities rather than implementation specifics, while modularization aids in breaking down a problem into manageable components.
|
||||
|
||||
1. **Abstraction:** This concept helps in reducing complexity by allowing programmers to concentrate on essential aspects and ignore unnecessary details.
|
||||
|
||||
|
||||
2. **Modularization:** By dividing problems into smaller sub-problems, programmers can tackle complex issues more efficiently.
|
||||
|
||||
|
||||
**Encapsulation** works closely with these concepts by bundling data and methods that operate on that data into a single entity, such as a class in Java, thus hiding the internal state and requiring interaction only through specified methods.
|
||||
|
||||
@@ -37,21 +35,20 @@ Two significant programming principles are reviewed: **abstraction** and **modul
|
||||
Several fundamental data structures form the backbone of programming:
|
||||
|
||||
- **Primitive Data Types:** These include Integers, Floats, Characters, and Booleans, which represent basic data values.
|
||||
|
||||
|
||||
- **Composite Data Types:** These include essential data structures such as:
|
||||
|
||||
|
||||
- **Arrays:** Collections of elements identified by indices, commonly used in mathematical contexts.
|
||||
|
||||
|
||||
- **Linked Lists:** Data elements structured as nodes, each containing information and a link to the next node.
|
||||
|
||||
|
||||
- **Stacks:** Last-in-First-out (LIFO) structures that allow insertion and deletion at one end, termed the top.
|
||||
|
||||
|
||||
- **Queues:** First-in-First-out (FIFO) structures where insertion occurs at the rear and deletion at the front.
|
||||
|
||||
|
||||
- **Trees:** Non-linear structures representing hierarchical relationships, ideal for organizing data hierarchically.
|
||||
|
||||
|
||||
- **Graphs:** These consist of nodes and edges, representing pairwise relationships among elements.
|
||||
|
||||
|
||||
## Concrete Implementations of ADTs
|
||||
|
||||
@@ -61,4 +58,4 @@ Within programming languages, data structures can act as concrete implementation
|
||||
|
||||
In software development, the foundation of a solution begins with the specification of a problem, followed by the formulation of an **algorithm**. An algorithm is a defined sequence of operations that transforms inputs into outputs, effectively addressing the problem. As programmers develop algorithms, they gain insights into which data structures may best suit their needs, leading to efficient solutions.
|
||||
|
||||
Ultimately, the understanding and application of data structures and ADTs are paramount in achieving effective software design and development, making them a cornerstone of efficient programming practices.
|
||||
Ultimately, the understanding and application of data structures and ADTs are paramount in achieving effective software design and development, making them a cornerstone of efficient programming practices.
|
||||
|
@@ -1,27 +1,23 @@
|
||||
## Advantages
|
||||
|
||||
- This has the advantage of making certain actions easier to perform but at the cost of increased maintenance of the code overall.
|
||||
|
||||
- Allows traversal of nodes in both direction which is not possible in singly linked list.
|
||||
|
||||
- Can allocate or de-allocate memory easily when required during its execution.
|
||||
|
||||
- It is one of most efficient data structure to implement when traversing in both direction is required.
|
||||
## Disadvantages
|
||||
|
||||
## Disadvantages
|
||||
|
||||
- Using extra memory when compared to array and singly linked list.
|
||||
|
||||
- Slow in search as its elements are stored randomly in memory, hence elements are accessed sequentially (no direct access is allowed).
|
||||
|
||||
## ADT Liner list could be implemented by two ways:
|
||||
## ADT Liner List Could Be Implemented by Two Ways:
|
||||
|
||||
- Array
|
||||
- Used when you search is the highest priority
|
||||
|
||||
- Linked list
|
||||
- Singly linked list
|
||||
- Used when you addition/deletion is the highest priority
|
||||
|
||||
|
||||
- Doubly linked list
|
||||
- Used when you addition/deletion is the highest priority
|
||||
- Navigate next and pervious
|
||||
- Navigate next and previous
|
||||
|
@@ -28,37 +28,34 @@ For example, a constructor header like `public PrintWriter(String fileName) thro
|
||||
At the core of Java's exception handling is the **Throwable** class, which serves as the superclass for all exceptions and errors. It has two key subclasses:
|
||||
|
||||
- **Error**: Indicates serious problems that a user application should not catch.
|
||||
|
||||
|
||||
- **Exception**: Represents conditions that a user application might want to catch.
|
||||
|
||||
|
||||
Within the Exception hierarchy, we find numerous subclasses such as **IOException** and **RuntimeException**, which themselves have numerous subclasses. For example:
|
||||
|
||||
- **IOException** can lead to specific exceptions like:
|
||||
|
||||
|
||||
- **FileNotFoundException**
|
||||
|
||||
|
||||
- **EOFException**
|
||||
|
||||
|
||||
- **RuntimeException** encompasses:
|
||||
|
||||
|
||||
- **ArithmeticException**
|
||||
|
||||
|
||||
- **IndexOutOfBoundsException**
|
||||
|
||||
|
||||
- **NullPointerException**
|
||||
|
||||
|
||||
- **IllegalArgumentException**
|
||||
|
||||
|
||||
## Dealing with Exceptions
|
||||
|
||||
Handling exceptions can be approached in two primary ways:
|
||||
|
||||
- **Catching the Exception**: This involves writing code to handle the exception immediately where it occurs. To achieve this, any potentially exception-generating code must reside within a **try** block, followed by one or more **catch** blocks that process the exception.
|
||||
|
||||
|
||||
- **Propagating the Exception**: Alternatively, the method can propagate the exception, allowing higher levels of the program to handle it. This is done by throwing the exception again after catching it or not catching it at all.
|
||||
|
||||
|
||||
### Catch Blocks Example
|
||||
|
||||
@@ -73,7 +70,7 @@ A fundamental aspect of handling exceptions is the use of a **try** and **catch*
|
||||
> }
|
||||
> ```
|
||||
|
||||
Here, _XXXException_ can be various types of exceptions, such as **IOException** or **RuntimeException**. When multiple types of exceptions can be thrown, several catch blocks can be utilized, ordered from the most specific to the most general. For instance:
|
||||
Here, *XXXException* can be various types of exceptions, such as **IOException** or **RuntimeException**. When multiple types of exceptions can be thrown, several catch blocks can be utilized, ordered from the most specific to the most general. For instance:
|
||||
|
||||
> ```
|
||||
> try {
|
||||
@@ -127,4 +124,4 @@ In a sample application, if the main() method adds **throws IOException**, the m
|
||||
|
||||
## Final Thoughts on Exception Handling
|
||||
|
||||
Java's exception handling framework is robust and designed to enable developers to write code that can gracefully manage unexpected problems. This system incorporates custom exceptions using the **throw** keyword, enjoyable error messages, and fine-tuned control over program flow. The use of exception handling not only aids in maintaining the reliability of applications but also provides clearer diagnostic messages for debugging. Overall, proper understanding and implementation of Java exceptions are essential for writing resilient Java applications.
|
||||
Java's exception handling framework is robust and designed to enable developers to write code that can gracefully manage unexpected problems. This system incorporates custom exceptions using the **throw** keyword, enjoyable error messages, and fine-tuned control over program flow. The use of exception handling not only aids in maintaining the reliability of applications but also provides clearer diagnostic messages for debugging. Overall, proper understanding and implementation of Java exceptions are essential for writing resilient Java applications.
|
||||
|
@@ -7,9 +7,8 @@ This study material provides a concise overview of the Abstract Data Type (ADT)
|
||||
The Linear List can be implemented using different structures, including linked lists. The main focus here is on:
|
||||
|
||||
- Linear List based on LinkedList
|
||||
|
||||
|
||||
- Doubly-linked list
|
||||
|
||||
|
||||
Each of these implementations has its unique characteristics, advantages, and considerations.
|
||||
|
||||
@@ -18,13 +17,12 @@ Each of these implementations has its unique characteristics, advantages, and co
|
||||
Understanding the size of primitive types is fundamental in memory allocation:
|
||||
|
||||
- **boolean & byte** - 1 byte
|
||||
|
||||
|
||||
- **char & short** - 2 bytes
|
||||
|
||||
|
||||
- **int & float** - 4 bytes
|
||||
|
||||
|
||||
- **long & double** - 8 bytes
|
||||
|
||||
|
||||
It's important to note that, in modern 64-bit Java Virtual Machines (JVM), the minimum size of an object is 16 bytes due to the header size and padding requirements.
|
||||
|
||||
@@ -33,9 +31,8 @@ It's important to note that, in modern 64-bit Java Virtual Machines (JVM), the m
|
||||
When comparing Array Lists and Linked Lists:
|
||||
|
||||
- **Addition and Removal**: Linked Lists excel in scenarios where frequent addition and removal of elements are required due to their dynamic size and absence of resizing overhead.
|
||||
|
||||
|
||||
- **Memory Overhead**: Linked Lists consume more memory because each node contains a reference to both the next and, in doubly-linked lists, the previous node, which increases complexity and size.
|
||||
|
||||
|
||||
## Memory Allocation Concepts
|
||||
|
||||
@@ -52,48 +49,43 @@ A linked list is a collection of nodes where each node contains data and a refer
|
||||
Some common operations performed on linked lists include:
|
||||
|
||||
- **Insertion**: Nodes may be inserted at the beginning, middle, or end of the list, requiring adjustments of pointers accordingly.
|
||||
|
||||
|
||||
- **Removal**: Similar to insertion, removal requires accessing the right node and adjusting pointers to maintain list integrity.
|
||||
|
||||
|
||||
### Algorithm Visualizations
|
||||
|
||||
Visual representations can help understand operations such as inserting or deleting nodes. For example, to insert a node in a linked list, one must:
|
||||
|
||||
1. Create the new node.
|
||||
|
||||
|
||||
2. Adjust the pointers of the surrounding nodes to include the new node.
|
||||
|
||||
|
||||
## Doubly-Linked Lists
|
||||
|
||||
Doubly-linked lists add an extra pointer, allowing traversal in both forward and backward directions, enhancing flexibility:
|
||||
|
||||
- **Advantages**: They can traverse in both directions and manage dynamic memory more efficiently.
|
||||
|
||||
|
||||
- **Disadvantages**: They require more memory for pointers and tend to have slower access times due to their random memory allocation.
|
||||
|
||||
|
||||
### Inserting and Deleting in Doubly-Linked Lists
|
||||
|
||||
The process of inserting or deleting nodes involves managing the **prev** and **next** pointers to maintain the structure of the list. As illustrated:
|
||||
|
||||
1. For insertion, properly link the new node with its neighbors.
|
||||
|
||||
|
||||
2. For deletion, ensure that surrounding nodes bypass the removed node, effectively maintaining list integrity.
|
||||
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
In conclusion, choosing between an array and a linked list largely depends on the intended operations:
|
||||
|
||||
- **Arrays** are optimal for scenarios where quick search operations are prioritized.
|
||||
|
||||
- **Linked Lists** are preferred for scenarios where insertion and deletion operations are frequent, with variations including:
|
||||
|
||||
- **Singly Linked List**: Best suited for simple sequential access and minimal memory overhead.
|
||||
|
||||
- **Doubly Linked List**: Ideal when navigating both forwards and backwards is necessary.
|
||||
|
||||
|
||||
Understanding these structures and their operations is essential for effective programming and data management.
|
||||
- **Linked Lists** are preferred for scenarios where insertion and deletion operations are frequent, with variations including:
|
||||
|
||||
- **Singly Linked List**: Best suited for simple sequential access and minimal memory overhead.
|
||||
|
||||
- **Doubly Linked List**: Ideal when navigating both forwards and backwards is necessary.
|
||||
|
||||
Understanding these structures and their operations is essential for effective programming and data management.
|
||||
|
@@ -1,4 +1,5 @@
|
||||
## What is an interface?
|
||||
## What is an Interface?
|
||||
|
||||
- An interface is a device or a system that unrelated entities use to interact.
|
||||
- A remote control is an interface between you and a television set.
|
||||
|
||||
@@ -6,10 +7,7 @@ basically the interface has and abstract method which classes have to implement
|
||||
|
||||
Concert realisation of the otherwise abstract method.
|
||||
|
||||
|
||||
|
||||
|
||||
## What is a linked list?
|
||||
## What is a Linked List?
|
||||
|
||||
- On the linked list every node is an object.
|
||||
- Has more memory overhead than an ArrayList.
|
||||
@@ -17,6 +15,6 @@ Concert realisation of the otherwise abstract method.
|
||||
- It mainly allows efficient *insertion* and *deletion* operations compared to arrays
|
||||
- Its dynamic, the size of it changes with every change.
|
||||
|
||||
# Protected
|
||||
prevents the method to be used by anyone but its sub classes.
|
||||
# Protected
|
||||
|
||||
prevents the method to be used by anyone but its sub classes.
|
||||
|
@@ -7,41 +7,38 @@ A queue is an important abstract data type (ADT) characterised by its FIFO (Firs
|
||||
## Key Concepts of Queues
|
||||
|
||||
- **Structure:** A queue consists of two primary ends:
|
||||
|
||||
- _Front:_ The position from which elements are removed.
|
||||
|
||||
- _Rear:_ The position where elements are added.
|
||||
|
||||
|
||||
- *Front:* The position from which elements are removed.
|
||||
|
||||
- *Rear:* The position where elements are added.
|
||||
|
||||
- **Core Operations:** The basic operations associated with a queue are:
|
||||
|
||||
|
||||
- **isEmpty():** Checks if the queue is empty.
|
||||
|
||||
|
||||
- **peek():** Returns the front element without removing it.
|
||||
|
||||
|
||||
- **put(x):** Adds an element x at the rear of the queue.
|
||||
|
||||
|
||||
- **remove():** Removes and returns the front element.
|
||||
|
||||
|
||||
## Queue Applications
|
||||
|
||||
Queues have various applications due to their structure, such as:
|
||||
|
||||
- CPU and disk scheduling, where resources are shared among multiple consumers.
|
||||
|
||||
|
||||
- Buffering in asynchronous data transfers like I/O operations, where data may not be received at the same rate as it is sent.
|
||||
|
||||
|
||||
- Handling jobs in a network printer which generally follows a FIFO order.
|
||||
|
||||
|
||||
## Queue Representation
|
||||
|
||||
Queues can be implemented in two ways:
|
||||
|
||||
- **Linear Array Queue:** Uses a one-dimensional array along with pointers for front and rear.
|
||||
|
||||
|
||||
- **Circular Array Queue:** Employs a circular structure to efficiently utilize array space, preventing the needs of shifting elements when the array is full.
|
||||
|
||||
|
||||
## Linear Queue Representation
|
||||
|
||||
@@ -56,20 +53,18 @@ Queue: A B C D (front = 1, rear = 4)
|
||||
A circular queue, uses the following logic:
|
||||
|
||||
- Front points 'anti-clockwise' from the first element while rear points to the last inserted element.
|
||||
|
||||
|
||||
- Utilizes the modulo operator to wrap around the indices as elements are added or removed.
|
||||
|
||||
|
||||
## Implementation of a Circular Queue
|
||||
|
||||
The implementation comprises several stages:
|
||||
|
||||
1. **Initialization:** Set front and rear to 0.
|
||||
|
||||
|
||||
2. **Insertion:** Update the rear index with a modulo operation. For example, rear=(rear+1)\%queue.length.
|
||||
|
||||
|
||||
3. **Removal:** Increment the front index to remove an element.
|
||||
|
||||
|
||||
## Challenges with Circular Queues
|
||||
|
||||
@@ -77,26 +72,25 @@ One of the critical issues with circular queues is distinguishing between a full
|
||||
|
||||
## Queue Implementation Using Array
|
||||
|
||||
The _ArrayQueue_ class illustrates array-based implementation:
|
||||
The *ArrayQueue* class illustrates array-based implementation:
|
||||
|
||||
``` java
|
||||
public class ArrayQueue implements Queue { ... }
|
||||
```
|
||||
|
||||
This class defines data members like _front_ and _rear_, along with methods for manipulating the queue.
|
||||
This class defines data members like *front* and *rear*, along with methods for manipulating the queue.
|
||||
|
||||
## Queue Methods Overview
|
||||
|
||||
Here are key methods defined in the Queue interface:
|
||||
|
||||
1. **isEmpty():** Returns true if the queue is empty.
|
||||
|
||||
|
||||
2. **peek():** Returns the front element or null if the queue is empty.
|
||||
|
||||
|
||||
3. **put(Object theObject):** Adds an element to the queue and may increase array length if the queue is full.
|
||||
|
||||
|
||||
4. **remove():** Removes the front element and updates the front pointer to the next element.
|
||||
|
||||
|
||||
## Queue Implementation Using Linked List
|
||||
|
||||
@@ -111,10 +105,9 @@ This structure provides constant time complexity for insertions and deletions, o
|
||||
## Summarizing Queue Operations
|
||||
|
||||
- **Adding Elements:** In a linked implementation, a new node is created and linked appropriately.
|
||||
|
||||
|
||||
- **Removing Elements:** The front element is removed and the front pointer is updated.
|
||||
|
||||
|
||||
## Conclusion
|
||||
|
||||
Queues are fundamental data structures in computer science with a range of applications spanning from scheduling tasks to implementing buffers. Their efficient management of elements through well-defined operations supports numerous algorithms and data handling strategies in programming.
|
||||
Queues are fundamental data structures in computer science with a range of applications spanning from scheduling tasks to implementing buffers. Their efficient management of elements through well-defined operations supports numerous algorithms and data handling strategies in programming.
|
||||
|
@@ -7,4 +7,4 @@
|
||||
| The SLL occupies less memory than DLL as it has only 2 fields. | The DLL occupies more memory than SLL as it has 3 fields. |
|
||||
| Complexity of deletion with a given node is O(n), because the previous node needs to be known, and traversal takes O(n) | Complexity of deletion with a given node is O(1) because the previous node can be accessed easily |
|
||||
| A singly linked list consumes less memory as compared to the doubly linked list. | The doubly linked list consumes more memory as compared to the singly linked list. |
|
||||
| Singly linked list is relatively less used in practice due to limited number of operations | Doubly linked list is implemented more in libraries due to wider number of operations. For example [Java LinkedList](https://www.geeksforgeeks.org/linked-list-in-java/) implements Doubly Linked List. |
|
||||
| Singly linked list is relatively less used in practice due to limited number of operations | Doubly linked list is implemented more in libraries due to wider number of operations. For example [Java LinkedList](https://www.geeksforgeeks.org/linked-list-in-java/) implements Doubly Linked List. |
|
||||
|
@@ -1,35 +1,30 @@
|
||||
# Overview
|
||||
|
||||
|
||||
- A stack is ta LIFO list. Meaning "last in first out"
|
||||
- Access is allowed only from one end of the stack
|
||||
- adding an item is called pulsing the stack
|
||||
- retrieving an item is called popping the stack
|
||||
- Access is allowed only from one end of the stack
|
||||
- adding an item is called pulsing the stack
|
||||
- retrieving an item is called popping the stack
|
||||
|
||||
# Typical uses
|
||||
# Typical Uses
|
||||
|
||||
- Parentheses matching; ()), or (())
|
||||
- Parentheses matching; ()), or (())
|
||||
- compiler's syntax check for matching braces is implemented by using stack
|
||||
- The simplest application of a stack is to reverse a word.
|
||||
- You push a given word to stack - letter by letter - and then pop letters from the stack.
|
||||
- Another application is an "undo" mechanism in text editors;
|
||||
-this operation is accomplished by keeping all text changes in a stack
|
||||
|
||||
- The simplest application of a stack is to reverse a word.
|
||||
• You push a given word to stack - letter by letter - and then pop letters from the stack.
|
||||
# Parenthesis Count
|
||||
|
||||
- Another application is an "undo" mechanism in text editors;
|
||||
•this operation is accomplished by keeping all text changes in a stack
|
||||
- Methodology (logical steps to solve the problem):
|
||||
- scan expression from left to right;
|
||||
- when a left parenthesis is encountered, add its position to the stack;
|
||||
- when a right parenthesis is encountered, remove matching position from stack (more example in a moment).
|
||||
|
||||
# Parenthesis count
|
||||
# Try-catch-throw
|
||||
|
||||
- Methodology (logical steps to solve the problem):
|
||||
- scan expression from left to right;
|
||||
- when a left parenthesis is encountered, add its position to the stack;
|
||||
- when a right parenthesis is encountered, remove matching position from stack (more example in a moment).
|
||||
|
||||
# try-catch-throw
|
||||
|
||||
- When you enter a try block, push the address of this block onto a stack.
|
||||
- When you enter a try block, push the address of this block onto a stack.
|
||||
\
|
||||
- When an exception is thrown, pop the try block that is at the top of the stack; if the stack is empty, terminate the program.
|
||||
|
||||
- If the popped try block has no matching catch block, go back to the previous step.
|
||||
|
||||
- When an exception is thrown, pop the try block that is at the top of the stack; if the stack is empty, terminate the program.
|
||||
- If the popped try block has no matching catch block, go back to the previous step.
|
||||
- If the popped try block has a matching catch block, execute the matching catch block.
|
||||
|
@@ -9,29 +9,17 @@ Linear lists, which include arrays and linked lists, are ideal for serially orde
|
||||
### Examples of Hierarchical Data in Trees
|
||||
|
||||
- Corporate Structure:
|
||||
|
||||
|
||||
- In a company, positions such as president, vice presidents, managers, etc., can be represented in a tree format.
|
||||
|
||||
|
||||
- Object-Oriented Programming:
|
||||
|
||||
|
||||
- In Java, classes form a hierarchy where the Object class is at the top, followed by subclasses.
|
||||
|
||||
|
||||
## Tree Terminologies
|
||||
|
||||
Understanding tree terminologies is crucial for grasping more complex operations and implementations.
|
||||
|
||||
- **Depth:** The number of edges from the root node to a specific node. For example, if node G is three levels down from the root, its depth is 3.
|
||||
|
||||
|
||||
- **Height:** The height of a tree is defined as the number of levels it possesses. A tree's maximum depth helps determine its overall height.
|
||||
|
||||
|
||||
- **Degree of a Node:** This refers to the number of child nodes a specific node has. A tree where each node has a maximum of two children is termed a **binary tree**.
|
||||
|
||||
|
||||
### Binary Trees
|
||||
|
||||
@@ -42,13 +30,8 @@ A binary tree is defined such that each node has at most two children, known tra
|
||||
When analyzing binary trees, certain properties can be established:
|
||||
|
||||
- A binary tree of height h must have at least h nodes.
|
||||
|
||||
|
||||
- In a full binary tree, each node has either two children or none. It contains the maximum number of nodes defined as 2^h - 1.
|
||||
|
||||
|
||||
- The number of nodes and tree height relationship is succinctly expressed with the inequalities: h \leq n \leq 2^h -1.
|
||||
|
||||
|
||||
## Binary Operations and Traversals
|
||||
|
||||
@@ -59,47 +42,31 @@ Performing operations on binary trees is essential to manage and manipulate data
|
||||
Traversal techniques allow for processing each node in a specified order:
|
||||
|
||||
- **Pre-order Traversal:** Process the root, then traverse the left subtree, followed by the right subtree.
|
||||
|
||||
|
||||
- **In-order Traversal:** Visit the left subtree first, then process the root, followed by the right subtree.
|
||||
|
||||
|
||||
- **Post-order Traversal:** Traverse the left subtree, right subtree, and then process the root.
|
||||
|
||||
|
||||
- **Level-order Traversal:** Process nodes level by level from the root down to the leaves.
|
||||
|
||||
|
||||
### Arithmetic Expressions as Trees
|
||||
|
||||
Binary trees are particularly useful for representing arithmetic expressions. An _expression tree_ is structured such that:
|
||||
Binary trees are particularly useful for representing arithmetic expressions. An *expression tree* is structured such that:
|
||||
|
||||
- Leaves represent operands.
|
||||
|
||||
|
||||
- Non-leaf nodes denote operators.
|
||||
|
||||
|
||||
- Subtrees represent sub-expressions.
|
||||
|
||||
|
||||
## Conversion Between Expression Formats
|
||||
|
||||
Moving between infix, prefix, and postfix expressions requires constructing expression trees first.
|
||||
|
||||
1. Infix expression (a + b) can be converted to a postfix expression (a b +) by building the corresponding expression tree and performing a post-order traversal.
|
||||
|
||||
|
||||
## Constructing Binary Trees from Traversals
|
||||
|
||||
Creating a binary tree from given traversals (like in-order and pre-order) involves recognizing patterns in the data:
|
||||
|
||||
- From in-order and pre-order traversals, one identifies the root and splits left and right subtrees accordingly.
|
||||
|
||||
|
||||
- The process can illustrate various scenarios and result in multiple valid trees for the same traversal combinations.
|
||||
|
||||
|
||||
## Conclusion
|
||||
|
||||
Tree data structures are indispensable in computer science, providing efficient methods for data organization, retrieval, and management. Understanding their properties and operations enables clearer problem-solving strategies and effective programming techniques.
|
||||
Tree data structures are indispensable in computer science, providing efficient methods for data organization, retrieval, and management. Understanding their properties and operations enables clearer problem-solving strategies and effective programming techniques.
|
||||
|
@@ -1,50 +1,78 @@
|
||||
# Interfaces, Linked Lists, Array Lists
|
||||
|
||||
## Definitions
|
||||
|
||||
### Interface
|
||||
|
||||
A contract that defines methods, field variables, return types, a class must implement. An example of this is the `List` interface in Java.
|
||||
|
||||
### Linked List
|
||||
|
||||
A data structure where nodes are linked using pointers. Each node contains data - storing a value, and pointer - referencing the next node (and previous in doubly linked).
|
||||
|
||||
#### Types
|
||||
|
||||
- Singly Linked (Unidirectional)
|
||||
- Doubly Linked (Bidirectional)
|
||||
- Circular Linked (Last node points to first node)
|
||||
|
||||
### Array List
|
||||
|
||||
A resizable array-based data structure where elements are stored in contiguous memory locations. Arrays allow for random access through an index corresponding to a location in the array. When capacity is exceeded, the list can resize dynamically.
|
||||
|
||||
## Difference between Linked and Array Lists
|
||||
|
||||
- Memory Allocation
|
||||
- LL -> Dynamic; Array -> Contiguous
|
||||
- Performance
|
||||
- LL -> Good for Insert/Delete; Array -> Good for searching
|
||||
|
||||
## Use Case
|
||||
|
||||
### Linked List
|
||||
|
||||
#### Stacks / Queues
|
||||
|
||||
Linked lists can efficiently add or remove from either end.
|
||||
|
||||
- Stack: Singly Linked List, insert/remove at head. O(1)
|
||||
- Queue: Doubly Linked List, efficient tail and head operations (enqueue dequeue)
|
||||
|
||||
#### Task Scheduling
|
||||
|
||||
- Dynamic data, removing / adding tasks easier with linked list
|
||||
|
||||
#### Undo Function
|
||||
|
||||
- Doubly Linked List, track user actions. move back or forward allows for easy undo / redo
|
||||
|
||||
### Array List
|
||||
|
||||
#### Database Caching
|
||||
|
||||
- Frequent random access, ideal for storing cached records.
|
||||
|
||||
#### Dropdown Menus
|
||||
|
||||
- Store and dynamically resize when elements need to be added to UI drop-downs that change based on input.
|
||||
|
||||
#### Inventory Systems
|
||||
|
||||
- Elements added or accessed without many deletions, Array List would allow for predictable resizing.
|
||||
|
||||
## Implementation
|
||||
|
||||
### Interface
|
||||
|
||||
```java
|
||||
interface Interface {
|
||||
void method();
|
||||
int method2(int param)
|
||||
}
|
||||
```
|
||||
|
||||
### Linked List
|
||||
|
||||
```java
|
||||
class Node {
|
||||
int data;
|
||||
@@ -80,7 +108,9 @@ class LinkedList {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Array List
|
||||
|
||||
```java
|
||||
import java.util.ArrayList;
|
||||
class ArrayList {
|
||||
@@ -168,11 +198,13 @@ class Stack {
|
||||
```
|
||||
|
||||
## Parenthesis Matching
|
||||
|
||||
- Push opening brackets, closing brackets pop correspondingly, if no match, false.
|
||||
|
||||
## Dijkstra's Two-Stack Algorithm
|
||||
|
||||
- Eval parenthesized arithmetic expressions
|
||||
- One stack operands
|
||||
- One stack operators
|
||||
- Processes expression by push/pop elements on stacks, eval subexpression when closing parenthesis encountered.
|
||||
- Assumed expression is fully parenthesised
|
||||
- Assumed expression is fully parenthesised
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Write a Java method pop() for a stack implemented using an array.
|
||||
# Write a Java Method pop() for a Stack Implemented Using an Array.
|
||||
|
||||
```java
|
||||
public class Stack {
|
||||
|
@@ -4,6 +4,7 @@ To insert a node into a **binary search tree (BST)** while keeping the tree **ba
|
||||
2. After insertion, **rebalance the tree** (if necessary) to ensure that it remains balanced. A tree is considered balanced if the height difference between the left and right subtrees of any node is at most 1 (this is the **balanced binary tree** or **AVL tree** property).
|
||||
|
||||
### **Given Binary Search Tree**:
|
||||
|
||||
```
|
||||
10
|
||||
/ \
|
||||
@@ -21,6 +22,7 @@ We start by inserting **4** into the BST:
|
||||
- 4 is greater than 2, so 4 will be placed as the **right child** of 2.
|
||||
|
||||
After insertion, the tree looks like this:
|
||||
|
||||
```
|
||||
10
|
||||
/ \
|
||||
@@ -44,6 +46,7 @@ Since the tree is balanced at all levels, **no further rebalancing is necessary*
|
||||
### **Final Balanced Tree**:
|
||||
|
||||
The final tree after inserting 4 is:
|
||||
|
||||
```
|
||||
10
|
||||
/ \
|
||||
@@ -56,4 +59,4 @@ The final tree after inserting 4 is:
|
||||
|
||||
### **Conclusion**:
|
||||
|
||||
After inserting 4, the tree remains balanced and no rotations are needed.
|
||||
After inserting 4, the tree remains balanced and no rotations are needed.
|
||||
|
@@ -1,6 +1,7 @@
|
||||
# Describe a scenario where a stack data structure would be more suitable than a Queue
|
||||
# Describe a Scenario where a Stack Data Structure Would Be More Suitable than a Queue
|
||||
|
||||
A **stack data structure** is more suitable than a queue in scenarios where you need to process items in a **Last-In, First-Out (LIFO)** order
|
||||
|
||||
### Scenario: **Undo Operation in Text Editors**
|
||||
|
||||
- **Description**: In text editors, when a user types, deletes, or performs other actions, these operations are stored so they can be undone in reverse order of execution.
|
||||
@@ -36,5 +37,5 @@ A **stack data structure** is more suitable than a queue in scenarios where you
|
||||
- A **queue** is more suitable when processing items in a **First-In, First-Out (FIFO)** order, such as serving customer requests or scheduling tasks.
|
||||
- A stack is better when you need **reversal** or to **process the most recent element first**, such as undo operations, recursion, or browser backtracking.
|
||||
|
||||
Describe a scenario where a stack data structure would be more suitable than a
|
||||
Queue
|
||||
Describe a scenario where a stack data structure would be more suitable than a
|
||||
Queue
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# What is a binary search tree, and how does it differ from a regular binary tree?
|
||||
# What is a Binary search Tree, and how Does it Differ from a Regular Binary Tree?
|
||||
|
||||
### **Binary Search Tree (BST):**
|
||||
|
||||
@@ -38,6 +38,7 @@ A **Binary Tree** is a tree data structure where each node has at most two child
|
||||
#### Binary Tree:
|
||||
|
||||
A binary tree with no ordering constraints:
|
||||
|
||||
```
|
||||
10
|
||||
/ \
|
||||
@@ -45,11 +46,13 @@ A binary tree with no ordering constraints:
|
||||
/
|
||||
40
|
||||
```
|
||||
|
||||
- Node values are not in any specific order.
|
||||
|
||||
#### Binary Search Tree:
|
||||
|
||||
A binary search tree:
|
||||
|
||||
```
|
||||
10
|
||||
/ \
|
||||
@@ -64,13 +67,13 @@ A binary search tree:
|
||||
|
||||
---
|
||||
|
||||
### **Advantages of BST Over a General Binary Tree:**
|
||||
### **Advantages Of BST Over a General Binary Tree:**
|
||||
|
||||
1. **Efficient Searching**: Searching in a BST takes $O(h)$, where $h$ is the height of the tree. In a balanced BST, $h=O(logn)$.
|
||||
2. **Ordered Traversal**: In-order traversal of a BST produces the nodes in sorted order.
|
||||
3. **Efficient Range Queries**: BSTs can efficiently find all elements within a specific range.
|
||||
|
||||
### **Disadvantages of BST:**
|
||||
### **Disadvantages Of BST:**
|
||||
|
||||
1. If unbalanced (e.g., when nodes are inserted in sorted order), the BST can degrade to a linked list, resulting in $O(n)$ time for operations.
|
||||
2. Maintaining balance (e.g., in AVL or Red-Black Trees) adds complexity.
|
||||
2. Maintaining balance (e.g., in AVL or Red-Black Trees) adds complexity.
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# What is an interface in object-oriented programming and how does it differ from a class?
|
||||
# What is an Interface in Object-oriented Programming and how Does it Differ from a Class?
|
||||
|
||||
### **What is an Interface in Object-Oriented Programming?**
|
||||
### **What Is an Interface in Object-Oriented Programming?**
|
||||
|
||||
An **interface** is a contract in object-oriented programming (OOP) that defines a set of methods (and sometimes properties) that a class must implement. It specifies _what_ a class should do, but not _how_ it should do it.
|
||||
An **interface** is a contract in object-oriented programming (OOP) that defines a set of methods (and sometimes properties) that a class must implement. It specifies *what* a class should do, but not *how* it should do it.
|
||||
|
||||
Key characteristics of an interface:
|
||||
|
||||
@@ -12,6 +12,7 @@ Key characteristics of an interface:
|
||||
4. **No State**: Interfaces do not contain instance variables or state but may include constants.
|
||||
|
||||
#### Example in Java:
|
||||
|
||||
```java
|
||||
// Define an interface
|
||||
public interface Animal {
|
||||
@@ -33,7 +34,7 @@ public class Dog implements Animal {
|
||||
}
|
||||
```
|
||||
|
||||
### **What is a Class?**
|
||||
### **What Is a Class?**
|
||||
|
||||
A **class** is a blueprint for creating objects in OOP. It defines the structure (fields or attributes) and behavior (methods) of objects. Unlike interfaces, classes can have implementations, state, and behavior.
|
||||
|
||||
@@ -45,6 +46,7 @@ Key characteristics of a class:
|
||||
4. **Constructors**: Classes can have constructors to initialize objects.
|
||||
|
||||
#### Example in Java:
|
||||
|
||||
```java
|
||||
// Define a class
|
||||
public class Dog {
|
||||
@@ -73,13 +75,14 @@ public class Dog {
|
||||
|**Constructors**|Cannot have constructors.|Can have constructors to initialize objects.|
|
||||
|**Abstract**|Interfaces are entirely abstract (unless extended in modern versions).|Can be abstract or concrete.|
|
||||
|**Default Methods**|Starting from Java 8, interfaces can have default methods (methods with a body).|Classes always support method implementation.|
|
||||
### **When to Use an Interface?**
|
||||
|
||||
### **When To Use an Interface?**
|
||||
|
||||
- **Polymorphism**: When you want different classes to provide their specific implementation of the same behavior.
|
||||
- **Decoupling**: To decouple code by relying on abstractions rather than concrete classes.
|
||||
- **Multiple Inheritance**: When you need a class to inherit behavior from multiple sources.
|
||||
|
||||
### **When to Use a Class?**
|
||||
### **When To Use a Class?**
|
||||
|
||||
- When you need to define an object with both state and behavior.
|
||||
- When you need concrete implementations of methods.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Convert the infix expression A * (B + C) / D to a postfix expression
|
||||
# Convert the Infix Expression A * (B + C) / D to a Postfix Expression
|
||||
|
||||
To convert the infix expression `A * (B + C) / D` into postfix notation, we use the following rules:
|
||||
|
||||
@@ -16,19 +16,20 @@ To convert the infix expression `A * (B + C) / D` into postfix notation, we use
|
||||
#### Infix Expression: `A * (B + C) / D`
|
||||
|
||||
1. Start with the subexpression inside the parentheses `(B + C)`:
|
||||
|
||||
|
||||
- Convert `B + C` to postfix: `BC+`.
|
||||
2. Substitute the postfix for `(B + C)` back into the original expression:
|
||||
|
||||
|
||||
- The expression becomes `A * BC+ / D`.
|
||||
3. Process the multiplication (`*`) and division (`/`):
|
||||
|
||||
|
||||
- `A * BC+` becomes `ABC+*`.
|
||||
- `ABC+* / D` becomes `ABC+*D/`.
|
||||
|
||||
---
|
||||
|
||||
### **Final Postfix Expression**:
|
||||
|
||||
```
|
||||
ABC+*D/
|
||||
```
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Evaluate the postfix expression `6 2 3 + -.`
|
||||
# Evaluate the Postfix Expression `6 2 3 + -.`
|
||||
|
||||
### **Postfix Evaluation Rules**
|
||||
|
||||
@@ -13,25 +13,25 @@
|
||||
**Expression**: `6 2 3 + -`
|
||||
|
||||
1. **Read `6`**:
|
||||
|
||||
|
||||
- Push `6` onto the stack.
|
||||
- **Stack**: `[6]`
|
||||
2. **Read `2`**:
|
||||
|
||||
|
||||
- Push `2` onto the stack.
|
||||
- **Stack**: `[6, 2]`
|
||||
3. **Read `3`**:
|
||||
|
||||
|
||||
- Push `3` onto the stack.
|
||||
- **Stack**: `[6, 2, 3]`
|
||||
4. **Read `+`**:
|
||||
|
||||
|
||||
- Pop the top two operands (`3` and `2`).
|
||||
- Perform `2 + 3 = 5`.
|
||||
- Push the result (`5`) onto the stack.
|
||||
- **Stack**: `[6, 5]`
|
||||
5. **Read `-`**:
|
||||
|
||||
|
||||
- Pop the top two operands (`5` and `6`).
|
||||
- Perform `6 - 5 = 1`.
|
||||
- Push the result (`1`) onto the stack.
|
||||
@@ -42,4 +42,3 @@
|
||||
### **Final Result**:
|
||||
|
||||
The result of the postfix expression `6 2 3 + -` is **`1`**.
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Compare and contrast a queue with a stack.
|
||||
# Compare and Contrast a Queue with a Stack.
|
||||
|
||||
### **Comparison of Queue and Stack**
|
||||
### **Comparison Of Queue and Stack**
|
||||
|
||||
|**Aspect**|**Stack**|**Queue**|
|
||||
|---|---|---|
|
||||
@@ -47,4 +47,4 @@
|
||||
### **Summary**:
|
||||
|
||||
- A **stack** is suitable for tasks where the most recent action needs to be undone or processed first (**LIFO**).
|
||||
- A **queue** is ideal for tasks where the first action needs to be processed first (**FIFO**).
|
||||
- A **queue** is ideal for tasks where the first action needs to be processed first (**FIFO**).
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Consider a min heap with these elements: [4, 5, 6, 7, 8, 9, 10]. Insert 3 into this min heap.
|
||||
# Consider a Min Heap with These Elements: [4, 5, 6, 7, 8, 9, 10]. Insert 3 into This Min Heap.
|
||||
|
||||
In a **min heap**, the root node contains the smallest element, and every parent node is less than its children. When we insert a new element into a min heap, we follow these steps:
|
||||
|
||||
@@ -8,10 +8,13 @@ In a **min heap**, the root node contains the smallest element, and every parent
|
||||
### Given Min Heap:
|
||||
|
||||
The given min heap is represented as an array:
|
||||
|
||||
```csharp
|
||||
[4, 5, 6, 7, 8, 9, 10]
|
||||
```
|
||||
|
||||
This corresponds to the following binary tree:
|
||||
|
||||
```
|
||||
4
|
||||
/ \
|
||||
@@ -19,13 +22,17 @@ This corresponds to the following binary tree:
|
||||
/ \ / \
|
||||
7 8 9 10
|
||||
```
|
||||
|
||||
### **Step 1: Insert 3 into the Heap**
|
||||
|
||||
First, insert 3 at the end of the heap:
|
||||
|
||||
```csharp
|
||||
[4, 5, 6, 7, 8, 9, 10, 3]
|
||||
```
|
||||
|
||||
This corresponds to the following binary tree:
|
||||
|
||||
```
|
||||
4
|
||||
/ \
|
||||
@@ -35,6 +42,7 @@ This corresponds to the following binary tree:
|
||||
/
|
||||
3
|
||||
```
|
||||
|
||||
### **Step 2: Bubble Up**
|
||||
|
||||
Now, we need to **bubble up** the element `3` to restore the heap property. We compare `3` with its parent and swap if necessary:
|
||||
@@ -42,6 +50,7 @@ Now, we need to **bubble up** the element `3` to restore the heap property. We c
|
||||
- The parent of `3` is `7` (index 3). Since `3 < 7`, we swap them.
|
||||
|
||||
After the swap, the heap becomes:
|
||||
|
||||
```
|
||||
4
|
||||
/ \
|
||||
@@ -57,6 +66,7 @@ Now, we continue the bubbling up process:
|
||||
- The parent of `3` is `5` (index 1). Since `3 < 5`, we swap them.
|
||||
|
||||
After the swap, the heap becomes:
|
||||
|
||||
```
|
||||
4
|
||||
/ \
|
||||
@@ -86,6 +96,7 @@ After the swap, the heap becomes:
|
||||
### **Final Array Representation**:
|
||||
|
||||
The final min heap as an array is:
|
||||
|
||||
```csharp
|
||||
[3, 4, 6, 5, 8, 9, 10, 7]
|
||||
```
|
||||
|
@@ -1,4 +1,5 @@
|
||||
# Create an adjacency matrix for the following weighted undirected graph.
|
||||
# Create an Adjacency Matrix for the following Weighted Undirected Graph.
|
||||
|
||||
```
|
||||
A-3-B
|
||||
| |
|
||||
@@ -17,10 +18,10 @@ To create an **adjacency matrix** for the given **weighted undirected graph**, w
|
||||
|
||||
### **Graph Details**:
|
||||
|
||||
- **A -3- B**: There is an edge between A and B with weight 3.
|
||||
- **A -2- C**: There is an edge between A and C with weight 2.
|
||||
- **B -1- D**: There is an edge between B and D with weight 1.
|
||||
- **C -4- D**: There is an edge between C and D with weight 4.
|
||||
- **A -3B**: There is an edge between A and B with weight 3.
|
||||
- **A -2C**: There is an edge between A and C with weight 2.
|
||||
- **B -1D**: There is an edge between B and D with weight 1.
|
||||
- **C -4D**: There is an edge between C and D with weight 4.
|
||||
|
||||
---
|
||||
|
||||
@@ -49,4 +50,4 @@ Let's map the nodes to indices:
|
||||
- `B-D` has a weight of 1, so `matrix[1][3] = 1` and `matrix[3][1] = 1`.
|
||||
- `C-D` has a weight of 4, so `matrix[2][3] = 4` and `matrix[3][2] = 4`.
|
||||
|
||||
This adjacency matrix accurately represents the weighted undirected graph.
|
||||
This adjacency matrix accurately represents the weighted undirected graph.
|
||||
|
@@ -7,4 +7,3 @@ flowchart BT
|
||||
iae[IllegalArgumentException] --> re
|
||||
npe[NullPointerException] --> re
|
||||
```
|
||||
|
||||
|
@@ -0,0 +1 @@
|
||||
|
||||
|
@@ -4,4 +4,4 @@ Next job to be selected is one with highest prio
|
||||
|
||||
Add / Insert new item
|
||||
Remove / Delete highest or lowest prio
|
||||
Get / find highest or lowest prio
|
||||
Get / find highest or lowest prio
|
||||
|
Reference in New Issue
Block a user